programing

Linq Select에서 튜플 만들기

nasanasas 2020. 11. 1. 18:13
반응형

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 })
.AsEnumerable()
.Select(c => (Id: c.Id, Flag: c.Flag))
.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();

This method lets you work with Linq to Object instead Linq to Entities, so after call it,you can project the result of your query in whatever you need.The advantage of using AsEnumerable instead ToList is that AsEnumerable does not execute the query, it preserves deferred execution. It's good idea always filter your data first before call one of these methods.


I have found the answer:

codes = codesRepo.SearchFor(predicate)
      .ToList()
      .Select(c => Tuple.Create(c.Id, c.Flag))
      .ToList();

Use this method to do this and use the async.

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);

Just my two cents: this has caught me out a few times with the type names:

A few noddy examples:

    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);
    }

Regards.

참고URL : https://stackoverflow.com/questions/33545249/create-a-tuple-in-a-linq-select

반응형