10

EF5コードファーストを使用してdbルックアップを実行しようとしています。基本的な構造とテーブルの関係は次のとおりです。

public partial class Member
{
    public int    RecordID {get; set;}
    public string Name     {get; set;}
    ...etc.
    public virtual ICollection<MemberLink> MasterLinks {get; set;}
    public virtual ICollection<MemberLink> SlaveLinks {get; set;}
    public virtual ICollection<Message>    ReceivedMessages {get; set;}
    public virtual ICollection<Message>    SentMessages {get; set;}
}

public partial class MemberLink
{
    public int            RecordID     {get; set;}
    public virtual Member MasterMember {get; set;}
    public virtual Member SlaveMember  {get; set;}
    ...etc.
}

public partial class Message
{
    public int            RecordID  {get; set;}
    public virtual Member Sender    {get; set;}
    public virtual Member Recipient {get; set;}
    ...etc.
}

今、実行しようとしているクエリはMemberLinkRepositoryを使用しており、次のようになります。

public IList<MemberLink> GetMasterLinks(int p_MemberID)
{
    return Get()
           .Include ( memberLink => memberLink.MasterMember )
           .Include ( memberLink => memberLink.SlaveMember )
           .Include ( memberLink => memberLink.MasterMember.ReceivedMessages
                      .Where(
                      msg => msg.Sender.RecordID == memberLink.SlaveMember.RecordID) )
           .Where ( memberLink => memberLink.MasterMember.RecordID == p_MemberID)
           .ToList();

ただし、EF はネストされた Where が気に入らないようです。これを 2 つの別個のリポジトリ呼び出しに分割することもできます (実際、そうしなければならないように見えます) が、db への呼び出しを減らすために、1 回の不正な急襲で実行しようとしています。1回のクエリでこれを達成する方法を知っている人はいますか?

コードが私がやろうとしていることを示していることを願っています... そうでない場合は、もう少し詳しく説明しようと思います。

4

1 に答える 1

23

簡単に言うと、いいえです。EF では、 を使用してそれを行うことはできませんInclude()

これが可能になった場合の結果について考えてみてください。ある場合にMemberLink.MasterMember.ReceivedMessagesは完全に入力されますが、別の同一の外観のオブジェクトMemberLink.MasterMember.ReceivedMessagesでは、実際にはメッセージのサブセットになります! ReceivedMessages に追加しようとするとどうなりますか? 追加がフィルターに一致しない場合はどうなりますか? 傷だらけのバッグです。

答えは、投影を使用することです。

public IList<MemberLinkWithFiltereredMessages> GetMasterLinks(int p_MemberID)
{
    return Get()
        .Include(memberLink => memberLink.MasterMember)
        .Include(memberLink => memberLink.SlaveMember)
        .Where(memberLink => memberLink.MasterMember.RecordID == p_MemberID)
        .Select(memberLink => new MemberLinkWithFilteredMessages
        {
            MemberLink = memberLink,
            FilteredMessages = memberLink.MasterMember.ReceivedMessages
                .Where(msg => msg.Sender.RecordID == memberLink.SlaveMember.RecordID)
        })
        .ToList();
}

あなたが実際に行っているのは、特定の情報のサブセットを求めていることです。そのため、それについて明示してください。

于 2013-09-10T02:12:48.957 に答える