2011-05-01 3 views
10

를 인식하지 못하는LINQ 내가 그 방법이 방법

LINQ to Entities does not recognize the method 'Boolean IsMatch(System.Nullable`1[System.Int64], System.Nullable`1[System.Int64], System.Nullable`1[System.Int64], System.Nullable`1[System.Int64])' method, and this method cannot be translated into a store expression. 

은 무엇을 이유가 뭐야?
어떻게 해결할 수 있습니까?

+0

필터 란 무엇입니까? – SLaks

+0

@ SLaks ♦ : 죄송합니다. 질문을 isMatch 대리인으로 업데이트했습니다. – Naor

답변

14

LINQ - 투 - 엔티티는 쿼리에 임의의 .NET 방법을 사용할 수 없습니다 사용. 쿼리에 사용 된 각 방법은 SQL로 번역해야합니다. 이 조건은 데이터베이스 서버의 각 레코드에 대해 평가해야 어디 때문에 Expession<Func<entityType, bool>>를 반환하는 데 도움이되지 않습니다.

는 EF를 들어 코드가 같은 것을 의미

SELECT COUNT(*) 
FROM ... 
LEFT JOIN ... 
WHERE IsMatch(....) 

EF는이 SQL 서버 IsMatch 상당 모르기 때문에이 예외가 발생합니다 쿼리에 전달 함수 이름의 유효성을 검사하기 때문에.

Linq에 투 엔티티에서 사용할 수있는 유일한 가능 기능

는 미리 정의 된 맵핑

  • Cannonical functions는 SQL로 등가
  • EdmFunctions
  • EdmFunctions이 방법 EdmFunctionAttribute 표시되어

어느 .NET 기능을 SQL에 매핑합니다. 이 함수는 아무 것도하지 않거나 예외를 throw하기 때문에 일반적으로 공통 .NET 코드에서 실행할 수 없습니다. 그들은 Linq-to-entities를위한 함수 place holder 일뿐입니다. 사용 가능한 EdmFunctions은 다음과 같습니다

  • 미리 정의 된 EdmFunctions System.Data.Objects.EntityFunctions
  • 미리 정의 된 EdmFunctions에
  • System.Data.Objects.SqlClient.SqlFunctions에서 SQL 서버 (압축되지 않음)에 대한 사용자 정의 SQL 함수를 매핑 - 엔티티 디자이너에서 가져 오기 마법사가 당신의 소중한 표를 제외하고 (SQL 함수를 가져올 수 있습니다 함수). 그 후에 사용자 정의 정적 .NET 함수를 작성하고 EdmFunction 속성으로 디자이너에 가져온 SQL 함수에 맵핑 할 수 있습니다.
  • 사용자 정의 모델 정의 함수 - 이것은 EDMX 파일에 수동으로 작성된 특수 함수입니다 (XML로 열림). Entity SQL의 재사용 가능한 사용자 지정 부분입니다.

이미 다른 답변으로 how to create model defined function에 대해 설명했습니다. 매핑 된 만들기 SQL function is pretty similar. 수동으로 Function 요소를 EDMX에 생성하는 대신 EdmFunctionAttribute 속성을 가져온 SQL 함수에 매핑합니다.

2

IsMatch이라는 함수를 호출하는 식을 전달하고 있습니다.

LINQ to Entities는이 기능을 사용하여 수행 할 작업을 알지 못합니다.

+0

♦ : 질문을 업데이트했습니다 .. – Naor

+0

LINQ to Entities는 IsMatch를 SQL로 변환하는 방법을 알고 있지 않습니다. 표현식 트리로 바꿔야합니다. – SLaks

+3

♦ "표현식 트리로 대체하시오"는 것은 무엇을 의미합니까? – Naor

1

나는 비슷한 문제를 다루고 있었다. 내 작업 방식을 사용하기 전에 .AsEnumerable()을 사용하고있었습니다. 당신은 take a look at it here 일 수 있습니다.

+0

AsEnumerable을 추가하면 전체 테이블이 메모리로로드되고 companyId의 필터가 적용된 후에도 여전히 많은 결과가 나타납니다. – Naor

+0

@Naor : 몇 가지 결과로 작업했기 때문에 좋습니다. 너에 대해서 몰랐어. – Damb

0

Actualy, 당신은이 기능과 같이 계산 전달하는 것을 :

bool anonymous_delagate#123(T entity) 
{ 
    return entity.IsMatch(a,b,c,d) 
} 

을하지만,이, 그이 개체에서 호출 정말 어떤 방법 IsMatch 알고 EF을 필요 의미한다. 지금 recomending에 대해 생각할 수있는

만 것은 어떤 종류를 사용하는 동적 표현 단조 -이 쿼리 dynamicaly을 만들 수 있습니다. 또는 다른 모양으로 디자인을 재 작업하십시오.

Actualy는 acomplish하는 몇 가지 단계가 필요 쉽고 일반적인 방법이있다.

  1. 고정 방법 IsMatch을 만듭니다.
  2. Expression<{your entity here}, bool>을 직접 IsMatch에서 반환하십시오.
  3. 패스가 좋아 : 당신이 지금 가지고있는 ({your entity here}.IsMatch({parameters}))

나머지는 동일하게 유지 할 수 있습니다.

편집 : 예 이 특정 단체와 함께 작동합니다, 그래서 당신의 엔티티가 주문입니다 asume 것입니다. 자신의 실체를 대체합니다.

public static Expression<Func<Order, bool>> IsMatch(int id, ...) // static method, that returns filtering expression 
{ 
    return i => i.Id == id; // create the filtering criteria 
} 

그런 다음 원하는 전화 :

count(some_guid, Order.IsMatch(entityId, inviterId, routeId, luggageTypeId)); 
+0

예제를 제공 할 수 있습니까? 나는 마지막 두 단계를 이해하지 못했습니다. – Naor

+0

작성한 정적 IsMatch 메서드는 다른 함수를 기반으로하지 않는 대리자를 반환해야합니까? 예를 들어 "return i => i.MyMethod (id);"를 사용할 수 있습니까? – Naor

+0

아니요. eiter를 사용하여 표현식으로 completly 만들거나 Ladislav가 말한 것처럼 함수를 저장 프로 시저에 매핑하십시오. – Euphoric

관련 문제