2016-10-14 3 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

は私があなたの問題を理解してかどうかわからないんだけど、couldn(これは代わりに、クエリ式の構文の流暢な構文であるが、私は唯一の流暢な構文でこれを行う方法を知っていることを申し訳ありません)あなたは 'JOIN'を使っていますか? 'RIGHT JOIN'私は助けます。 –

答えて

0

私はEF4がインストールされていないEntity Frameworkのを使用していますが、あなたのようなものにできるはずですこれは単一のクエリを実行するだけです。

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あなたのコメントを読んだり、質問をより慎重に読んだりすると、私の答えは更新されました。今度は、1つのデータベースクエリを実行してから、メモリ内で「結合」操作を実行するだけです。これでもまだあなたの質問に答えることができない場合、私はあなたがしようとしているもののより明確な画像を得ることができるように、データベース呼び出しを取り巻くもう少しコードを共有していただけますか? – sam2929

関連する問題