[c#] Linq Select에서 튜플 만들기
Entity Framework 6.1.3을 사용하여 SQL Server 데이터베이스에서 데이터를 검색하는 C # 및 .NET Framework 4.5.1을 사용하고 있습니다.
나는 이것을 가지고있다:
codes = codesRepo.SearchFor(predicate)
.Select(c => new Tuple<string, byte>(c.Id, c.Flag))
.ToList();
그리고 실행하면 다음 메시지가 표시됩니다.
LINQ to Entities에서는 매개 변수가없는 생성자와 이니셜 라이저 만 지원됩니다.
내가 찾은 모든 예제가 대부분이 예제와 같기 때문에 Tuple을 어떻게 만들어야하는지 모르겠습니다.
나는 이것을 시도했다 :
codes = codesRepo.SearchFor(predicate)
.Select(c => Tuple.Create(c.Id, c.Flag))
.ToList();
그리고이 오류가 발생합니다.
LINQ to Entities는 ‘System.Tuple`2 [System.String, System.Byte] Create [String, Byte] (System.String, Byte)’메서드를 인식하지 못하며이 메서드는 저장소 식으로 변환 할 수 없습니다.
어디에 문제가 있습니까?
답변
octavioccl 의 대답 이 작동 하는 동안 먼저 쿼리 결과를 익명 유형으로 프로젝션 한 다음 열거 가능으로 전환하고 튜플로 변환하는 것이 좋습니다. 이렇게하면 쿼리가 데이터베이스에서 필요한 필드 만 검색합니다.
codes = codesRepo.SearchFor(predicate)
.Select(c => new { c.Id, c.Flag })
.AsEnumerable()
.Select(c => new Tuple<string, byte>(c.Id, c.Flag))
.ToList();
참고 : 위의 규칙은 EF6에 적용됩니다. EF Core는 자연스럽게 튜플 생성자를 통해 튜플 (프로젝션 또는 조인 / 그룹 키로)을 지원합니다. 예를 들어 원래 쿼리는 간단히 작동합니다.
codes = codesRepo.SearchFor(predicate)
.Select(c => new Tuple<string, byte>(c.Id, c.Flag))
.ToList();
그러나 Tuple.Create
방법은 아닙니다 (EF Core 2.x).
답변
C # 7에 대한 업데이트 된 답변입니다. 이제 더 간단한 구문을 사용하여 ValueTuples를 만들 수 있습니다.
codes = codesRepo.SearchFor(predicate)
.Select(c => new { c.Id, c.Flag })
.AsEnumerable()
.Select(c => (c.Id, c.Flag))
.ToList();
이제 튜플의 속성 이름을 지정할 수도 있습니다.
codes = codesRepo.SearchFor(predicate)
.Select(c => new { c.Id, c.Flag }) // anonymous type
.AsEnumerable()
.Select(c => (Id: c.Id, Flag: c.Flag)) // ValueTuple
.ToList();
따라서 Item1 또는 Item2로 사용하는 대신 Id 또는 Flag로 액세스 할 수 있습니다.
익명과 튜플 중 선택 에 대한 더 많은 문서
답변
이 시도:
codes = codesRepo.SearchFor(predicate)
.Select(c => Tuple.Create(c.Id, c.Flag))
.ToList();
LINQ to 엔터티에서 허용되지 않는다는 알림을 받았습니다.
또 다른 옵션은 선택하기 전에 결과를 메모리로 가져 오는 것입니다. 이 작업을 수행하려는 경우 .AsEnumerable () 전에 모든 필터링을 수행하는 것이 좋습니다. 이는 전체 테이블을 다시 가져온 다음 필터링하는 것과는 반대로 원하는 결과 만 가져 오는 것을 의미하기 때문입니다.
codes = codesRepo.SearchFor(predicate).AsEnumerable()
.Select(c => Tuple.Create(c.Id, c.Flag))
.ToList();
뿐만 아니라 Tuple.Create (c.Id, c.Flag)는 튜플 유형에서 코드를 좀 더 명시 적으로 만들고 싶다면 new Tuple (c.Id, c.Flag)로 변경 될 수 있습니다.
답변
에서 엔티티에 LINQ 당신은 익명의 유형에 또는 당신이 사용할 수있는 발행 DTO.To 피할에 투사 할 수 있습니다 AsEnumerable
확장 방법 :
codes = codesRepo.SearchFor(predicate).AsEnumerable().
.Select(c => new Tuple<string, byte>(c.Id, c.Flag))
.ToList();
이 방법은 당신이 작업을 할 수 있습니다 Object로 Linq를 대신 엔티티에 Linq에를 너무 후 호출, 당신은 당신이 사용하는 need.The 장점 어떤에서 쿼리의 결과 투사 할 수 있습니다 AsEnumerable
대신 ToList
즉 AsEnumerable
쿼리를 실행하지 않습니다, 그것은 실행을 연기 보존 식품. 이러한 메서드 중 하나를 호출하기 전에 항상 데이터를 먼저 필터링하는 것이 좋습니다.
답변
나는 답을 찾았습니다.
codes = codesRepo.SearchFor(predicate)
.ToList()
.Select(c => Tuple.Create(c.Id, c.Flag))
.ToList();
답변
이 방법을 사용하여이를 수행하고 비동기를 사용하십시오.
var codes = await codesRepo.SearchFor(predicate)
.Select(s => new
{
Id = s.Id,
Flag = s.Flag
}).FirstOrDefaultAsync();
var return_Value = new Tuple<string, byte>(codes.Id, codes.Flag);
답변
내 두 센트 : 이것은 유형 이름으로 몇 번 나를 잡았습니다.
고개를 끄덕이는 몇 가지 예 :
private Tuple<string, byte> v1()
{
return new Tuple<string, byte>("", 1);
}
private (string, int) v2()
{
return ("", 1);
}
private (string Id, byte Flag) v3()
{
return ("", 1);
}
문안 인사.