2011-02-04 2 views
3

나는이 일을 할 수있는 방법이 있음을 알고 있지만 알아 내려고 노력하면서 벽에 머리를 치고있었습니다. 이것은 잘 작동합니다 :linq을 사용하여 익명의 대표자를 선택하십시오

private GenericRecord CreateGeneric(GenericRecord g, Member m) 
{ 
    g.Member = m; 
    return g; 
} 

public IList<GenericRecord> ReportFromDatabase(DateTime startDate, DateTime endDate) 
{ 
    List<GenericRecord> returnRecords = new List<GenericRecord>(); 

    returnRecords.AddRange(from r in pjRepository.Records 
          join m in memberRepository.Members on r.SID equals m.MemberId.ToString() 
          where r.TransactionDate >= startDate && r.TransactionDate <= endDate 
          select CreateGeneric((GenericRecord)r, m)); 

    return returnRecords; 
} 

그러나 CreateGeneric 기능 없이는 할 수있는 방법이 있습니다. 델리게이트 함수를 인라인으로 어떻게 선택합니까? 나에게이 예외를 제공

returnRecords.AddRange(from r in pjRepository.Records 
         join m in memberRepository.Members on r.SID equals m.MemberId.ToString() 
         where r.TransactionDate >= startDate && r.TransactionDate <= endDate 
         select (delegate 
         { 
          GenericRecord g = (GenericRecord)r; 
          g.Member = m; 
          return g; 
         })); 

:

The type of the expression in the select clause is incorrect. Type inference failed in the call to 'Select'. 

편집 : 명령문과

람다 식을 : 또 다른 실패 시도는

returnRecords.AddRange((from r in pjRepository.Records 
         join m in memberRepository.Members on r.SID equals m.MemberId.ToString() 
         where r.TransactionDate >= startDate && r.TransactionDate <= endDate 
         select new { r, m }).Select(x => 
         { 
          GenericRecord g = (GenericRecord)x.r; 
          g.Member = x.m; 
          return g; 
         })); 

이 나에게주는 비 ody는 표현식 트리로 변환 될 수 없습니다.

답변

12

시도는 :

returnRecords.AddRange((from r in pjRepository.Records 
          join m in memberRepository.Members on r.SID equals m.MemberId.ToString() 
          where r.TransactionDate >= startDate && r.TransactionDate <= endDate 
          select new { r, m }).AsEnumerable().Select(x => 
          { 
           GenericRecord g = (GenericRecord)x.r; 
           g.Member = x.m; 
           return g; 
          })); 

키 다른 것을 AsEnumerable() 함수이다. IEnumerable은 IQueryable을 사용하며 Linq 공급자가 표현식 트리를 평가합니다. 이렇게하면 Linq 라이브러리가 두 번째 Select의 람다를 표현식 트리의 일부로 변환하지 못하게됩니다. 두 번째 Select는 대신 IQueryable 표현식 트리를 평가하여 생성 된 실제 메모리 컬렉션에서 변형을 수행합니다. 문이 끝나기 전에 쿼리를 평가해야하므로 (모든 요소를 ​​returnRecords에 추가 할 수 있으므로) 중요한 성능 차이가 없어야합니다.

+0

브릴리언트! 고맙습니다! –

0
Seem like this is what you are looking at: 
class Bila 
    { 
     public string Name; 
     public List<string> Adresses; 
    } 
    var justNumbers = Enumerable.Range(0, 10); 
Func<int,List<string>> foo = delegate(int j) 
    { 
     List<string> lst = new List<string>(); 
     for (int kk = 0; kk < j; kk++) 
     { 
      lst.Add("String_" + kk.ToString()); 
     } 
     return lst; 
    }; 
var zilla3 = (from x in justNumbers 
       select new Bila 
       { 
        Name = "Name_" + x.ToString(), 
        Adresses = foo(x), 
       }).ToArray(); 
+0

몇 가지 설명을 제공하십시오. – Parixit

관련 문제