LINQ는 목록 또는 단일 객체를 반환합니다
문제
이와 같은 LINQ에서 엔티티 쿼리가 있습니다.
var results = from r in entities.MachineRevision
where r.Machine.IdMachine == pIdMachine
&& r.Category == (int)pCategory
select r;
일반적으로 아래 코드를 사용하여 일부 결과가 반환되는지 확인합니다.
if (results.Count() > 0)
{
return new oMachineRevision(results.First().IdMachineRevision);
}
그러나 나는 받고있다 지원되지 않은 예고 에서 만약에 상태.
오류 메시지는 다음과 같습니다. '클로저 유형'유형의 일정한 값을 만들 수 없습니다. 이 맥락에서는 원시 유형 ( 'int32, string 및 guid') 만 지원됩니다.
주목하십시오 pcategory 열거 된 유형입니다.
해결책
편집하다: 업데이트에 따라 오류는 엔티티 클래스의 열거와 관련이있을 수 있습니다. 이것 좀 봐 블로그 항목 자세한 내용과 작업 원리. 쿼리 구문의 개선으로 원래 답변을 남겨두고 있습니다.
FirstOrdeFault를 사용하여 쿼리 자체에서 첫 번째 엔티티를 선택한 다음 결과가 NULL인지 확인하십시오.
int compareCategory = (int)pCategory; // just a guess
var result = (from r in entities.MachineRevision
where r.Machine.IdMachine == pIdMachine
&& r.Category == compareCategory
select r).FirstOrDefault();
if (result != null)
{
return new oMachineRevision(result.IdMachineRevision);
}
다른 팁
대신 FirstOrdeFault ()를 사용하고 NULL을 확인하지 않겠습니까? 카운트에 대한 쿼리의 이점을 볼 수없고 첫 번째 요소를 취할 수 없습니다.
LINQ의 표준 구현에서 연산자는 "선택"및 "여기서"맵을 ienumerable 또는 iqueryable을 반환하는 메소드에 맵핑됩니다. 따라서 사용될 때 표준 LINQ 메소드는 항상 단일 객체가 아닌 쿼리에서 ienumerable을 반환해야합니다.
그러나 LINQ 연산자의 후보 인 LINQ 방법은 Ienumerables를 반환하는 방법으로 제한되지 않으며, 모든 것을 반환하는 모든 방법을 선택할 수 있습니다.
"select"및 "여기서"라는 인스턴스 메소드가있는 경우 클래스에 특정한 단일 객체 또는 확장 메소드를 반환하고 표준 LINQ 대신 사용될 단일 객체를 반환합니다.
내 생각에 클래스에 정의 된 "Select"또는 "여기서"메소드가 LINQ가 IEnumerable<T>
.
쿼리 결과에 따라 다른 익명 객체가 생성 될 것이라는 것을 몰랐습니다. 나는 그들이 단지 결과가 유형의 ienumerable을 원했던 것 같아요
Foreach를 사용하는 것은 어떻습니까?
var results = from r in entities.MachineRevision
where r.Machine.IdMachine == pIdMachine
&& r.Category == pCategory
select r;
foreach( var r in results )
{
yield return new oMachineRevision( r.IdMachineRevision );
}
이것은 모든 암시 적 유형에도 적용됩니다. 나는 이것을 계속 잊어 버린 것을 인정해야하며 그것이 내가이 게시물을 만난 방법입니다.
당신이 가지고 있다면
class ClassA {
...
private string value;
...
public static implicit operator string(ClassA value)
{
return value.ToString();
}
...
}
당신은 비교를 위해 수업을 수술에 명시 적으로 던져야합니다.
그래서 나는 보통 이것을한다
var myClassAStr = myClassA.ToString();
var x = (from a in entites where a.ValToCompare == myClassAStr select a).first();
// do stuff with x
...
사용해보십시오
IENumerable<MachineRevision> results = from r in entities.MachineRevision
...
대신에.
나는 당신의 문제를 일으키는 VAR이라고 생각합니다.
편집하다:
오류 메시지를 읽으십시오. "유형 '클로저 유형'의 일정한 값을 만들 수 없습니다.이 맥락에서는 원시 유형 ( 'int32, string 및 guid') 만 지원됩니다."
이러한 비교 중 하나는 int, String 또는 Guid가 아닌 유형이 있습니다. 카테고리를 추측하고 있습니다.
r.Machine.IdMachine == pIdMachine && r.Category == pCategory
흥미롭게도 LinqToSQL 은이 구성을 허용합니다. LinqToentities가 왜 이것을 지원하지 않는지 모르겠습니다.
Lambda Expressions를 사용하여 원하는 항목을 선택할 수도 있다고 생각합니다.
var result = entities.MachineRevision
.Where(x => x.Machine.IdMachine == pIdMachine)
.Where(y => y.Category == (int)pCategory)
.FirstOrDefault();
if (result != null)
{
return new oMachineRevision(result.IdMachineRevision);
}
그런 다음 평소처럼 진행합니다