2016-10-14 7 views
0

전자 메일 주소의 배열로 전달되고 각 전자 메일 주소에 대해 해당 전자 메일 주소와 관련된 멤버의 numTotal 및 numActive를 반환해야합니다.목록에서 LINQ로 전달할 때 단일 데이터베이스 호출

전통적으로 구성원 테이블에서 쿼리하고 전달 된 전자 메일 배열에 구성원의 전자 메일 주소가있는 곳을 필터링합니다. 그러나 이것은 회원 테이블에있는 전자 메일의 개수가 포함 된 전자 메일 주소 목록 만 반환합니다. 대신 회원에게 이메일 주소가 있는지에 관계없이 제공되는 각 이메일 주소에 대한 기록이 필요합니다.

내 솔루션은 이메일 배열을 반복 한 다음 하위 쿼리를 수행하는 것입니다. 이 작업을하고 필요한 정보를 얻을 수 있지만 전화를 프로파일 링 할 때 EF가 각 전자 메일 주소/하위 쿼리에 대해 별도의 쿼리를 실행하고 있음을 알았습니다.

var result = (from email in emailAddresses 
       select new EmailAddressStats { 
       Total = membersQueryable.Any(m => m.Email == email), 
       Active = membersQueryable.Any(m => m.Email == email && m.IsActive) 
       }).ToList(); 

그래서 3 개의 이메일 주소를 전달하면 6 개의 별도 쿼리 (3 개의 이메일 주소 * 2 개의 하위 쿼리)가 표시됩니다.

배열을 .AsQueryable()을 사용하여 쿼리 가능하게 만들려고했으나 여전히 동일한 결과가 나타납니다.

SELECT ([totalSubquery]) AS Total, 
     ([activeSubquery]) AS Active 
FROM ???? 
WHERE EXISTS ('[email protected]', '[email protected]', '[email protected]') 

참고 :

이상적으로는 EF 같은 것을 생성하고 싶습니다 내가 4.

+1

가 나는 문제를 이해한다면 모르겠지만, 나오지 않았어 (이 대신 쿼리 식 구문의 유창함 문법에 있지만 난 단지 유창함 구문에서이 작업을 수행하는 방법을 알고 죄송합니다) 그걸 위해서'JOIN'을 사용하지 않습니까? '맞다. 나는 맞 읍시다. –

답변

0

내가 EF4가 설치되지 않은 엔티티 프레임 워크를 사용하고,하지만 당신은 같은 것을 할 수 있어야한다 이것은 하나의 쿼리 만 수행합니다.

List<EmailAddressStats> GetEmailAddressStats(string[] emailAddresses) 
{ 
    var returnList = emailAddresses.Select(e => new EmailAddressStats { Email = e }) 
            .ToList(); 

    // I don't know what your context is actually called so I'm just calling it MemberDatabaseContext) 
    using (var dbContext = new MemberDatabaseContext()) 
    { 
     // Query the database once with a single query to get all of the relevant members 
     var membersWithEmailAddress = dbContext.Members.Where(m => emailAddresses.Contains(m.Email)) 
                 .Select(m => new { Email = m.Email, IsActive = m.IsActive }) 
                 .ToList(); 

     // Update the email stats by analyzing the member info in memory 
     foreach (var emailStat in returnList) 
     { 
      emailStat.Total = membersWithEmailAddress.Count(m => m.Email == emailStat.Email); 
      emailStat.Active = membersWithEmailAddress.Count(m => m.Email == emailStat.Email && m.isActive); 
     } 
    } 

    return returnList; 
}  

+0

이메일 주소가 전달 목록에있는 회원 만 포함됩니다. 모든 이메일 주소에 대한 기록을 보유하고 있어야합니다. 누군가가 가지고 있든 없든 관계없이 필터링 된 회원 목록 대신 이메일 목록을보고 있습니다. –

+0

@ AndrésNava-.NET 귀하의 의견을 읽고 질문을 자세히 읽은 후에 답변을 업데이트했습니다. 이제는 하나의 데이터베이스 쿼리 만 수행 한 다음 메모리에서 "조인"연산을 수행해야합니다. 그래도 여전히 질문에 답을 얻지 못하면 데이터베이스 호출을 둘러싼 코드를 좀 더 공유하여 내가하려는 일에 대한 명확한 그림을 얻을 수 있습니까? – sam2929