Entity Framework- " 'Closure type'유형의 상수 값을 만들 수 없습니다…"오류
오류가 발생하는 이유 :
'Closure type'유형의 상수 값을 만들 수 없습니다. 이 컨텍스트에서는 기본 형식 (예 : Int32, String 및 Guid) 만 지원됩니다.
다음 Linq 쿼리를 열거하려고 할 때?
IEnumerable<string> searchList = GetSearchList();
using (HREntities entities = new HREntities())
{
var myList = from person in entities.vSearchPeople
where upperSearchList.All( (person.FirstName + person.LastName) .Contains).ToList();
}
업데이트 : 문제를 분리하기 위해 다음을 시도하면 동일한 오류가 발생합니다.
where upperSearchList.All(arg => arg == arg)
그래서 문제는 All 메서드에있는 것 같습니다. 맞죠? 어떤 제안?
"WHERE ... IN"조건에 해당하는 작업을 수행하려는 것 같습니다. LINQ to Entities 를 사용하여 이러한 유형의 쿼리를 수행하는 방법에 대한 예제는 LINQ to Entities 를 사용하여 'WHERE IN'스타일 쿼리를 작성하는 방법을 확인하세요 .
또한 .Contains
괄호가 뒤에 나오지 않아 컴파일러가 전체 술어를 람다 식으로 인식 하게되므로이 경우 오류 메시지가 특히 유용 하지 않다고 생각합니다 .
저는 지난 6 개월 동안 EF 3.5로이 제한과 싸우며 보냈고 제가 세상에서 가장 똑똑한 사람은 아니지만이 주제에 대해 유용한 정보를 제공 할 것이라고 확신합니다.
50 마일 높이의 "OR 스타일"식 트리를 늘려서 생성 된 SQL은 쿼리 실행 계획이 좋지 않습니다. 나는 수백만 개의 행을 다루고 있으며 그 영향은 상당합니다.
ID로 많은 엔티티를 찾는 경우 도움이되는 SQL 'in'을 수행하는 약간의 해킹이 있습니다.
private IEnumerable<Entity1> getByIds(IEnumerable<int> ids)
{
string idList = string.Join(",", ids.ToList().ConvertAll<string>(id => id.ToString()).ToArray());
return dbContext.Entity1.Where("it.pkIDColumn IN {" + idList + "}");
}
여기서 pkIDColumn은 Entity1 테이블의 기본 키 ID 열 이름입니다.
그러나 계속 읽으십시오!
이것은 괜찮지 만 내가 찾아야 할 ID가 이미 있어야합니다. 때로는 내 표현이 다른 관계에 도달하기를 원하며 내가 가진 것은 연결된 관계에 대한 기준입니다.
시간이 더 있다면 이것을 시각적으로 표현하려고했지만 잠시만이 문장을 공부하지는 않습니다. Person, GovernmentId 및 GovernmentIdType 테이블이있는 스키마를 고려하십시오. Andrew Tappert (Person)에는 두 개의 ID 카드 (GovernmentId)가 있는데, 하나는 Oregon (GovernmentIdType)이고 다른 하나는 Washington (GovernmentIdType)입니다.
이제 그것으로부터 edmx를 생성하십시오.
이제 특정 ID 값 (예 : 1234567)을 가진 모든 사람을 찾고 싶다고 상상해보십시오.
이것은 다음과 같이 단일 데이터베이스 적중으로 수행 할 수 있습니다.
dbContext context = new dbContext();
string idValue = "1234567";
Expression<Func<Person,bool>> expr =
person => person.GovernmentID.Any(gid => gid.gi_value.Contains(idValue));
IEnumerable<Person> people = context.Person.AsQueryable().Where(expr);
여기에 하위 쿼리가 표시됩니까? 생성 된 SQL은 하위 쿼리 대신 '조인'을 사용하지만 효과는 동일합니다. 요즘 SQL 서버는 어쨌든 커버 아래에서 조인으로 하위 쿼리를 최적화하지만 어쨌든 ...
이 작업의 핵심은 표현식 내부의 .Any입니다.
오류의 원인을 찾았습니다 (Framework 4.5를 사용하고 있습니다). 문제는 "Contains"-매개 변수로 전달되는 복합 유형 인 EF가 SQL 쿼리로 변환 할 수 없다는 것입니다. EF는 SQL 쿼리에서 int, string ...과 같은 단순한 유형 만 사용할 수 있습니다.
this.GetAll().Where(p => !assignedFunctions.Contains(p))
GetAll은 복합 유형 (예 : "함수")의 개체 목록을 제공합니다. 따라서 여기에서 SQL 쿼리에서이 복잡한 유형의 인스턴스를 수신하려고합니다.이 인스턴스는 자연스럽게 작동하지 않습니다!
내 목록에서 내 검색에 적합한 매개 변수를 추출 할 수 있다면 다음을 사용할 수 있습니다.
var idList = assignedFunctions.Select(f => f.FunctionId);
this.GetAll().Where(p => !idList.Contains(p.FunktionId))
이제 EF는 더 이상 작동 할 복잡한 유형 "함수"를 갖지 않지만 예를 들어 단순 유형 (long)을 사용합니다. 그리고 그것은 잘 작동합니다!
.All 함수에 사용 된 배열 개체가 null 인 경우이 오류 메시지가 나타납니다. 배열 개체 (귀하의 경우 upperSearchList)를 초기화 한 후 오류가 사라졌습니다.이 경우 오류 메시지가 잘못되었습니다.
여기서 upperSearchList.All (arg => person.someproperty.StartsWith (arg)))
'Nice programing' 카테고리의 다른 글
Java SSL 디버그 로깅 제한 (0) | 2020.10.10 |
---|---|
알림이 표시 될 때 사용자가 권한을 부여하려는 경우 Android '화면 오버레이 감지 됨'메시지 (0) | 2020.10.10 |
생성자를 명시 적으로 삭제하는 이유는 무엇입니까? (0) | 2020.10.10 |
git fast-forwarding이란 무엇입니까? (0) | 2020.10.10 |
ADL이 함수 템플릿을 찾지 못하는 이유는 무엇입니까? (0) | 2020.10.10 |