これは、クラスとして説明されている、私が扱っている単純化されたテーブルのセットです。T4 テンプレートを使用して単純な POCO を作成しています。 質問を混乱させる可能性のあるすべてのクラスの必須ではないプロパティをすべて削除しました。
public class MarketingPlan
{
public guid MarketingPlanID { get; set; }
public bool Disabled { get; set; }
public virtual ICollection<MarketingPlanItem> MarketingPlanItems { get; set; }
}
public partial class MarketingPlanItem
{
public System.Guid MarketingPlanItemID { get; set; }
public System.Guid MarketingPlanID { get; set; }
public System.Guid MarketingPlanItemTypeID { get; set; }
public bool Disabled { get; set; }
public Nullable<System.Guid> EmailTemplateID { get; set; }
public virtual EmailTemplate EmailTemplate { get; set; }
public virtual MarketingPlanItemType MarketingPlanItemType { get; set; }
}
public partial class EmailTemplate
{
public System.Guid EmailTemplateID { get; set; }
}
public partial class MarketingPlanItemType
{
public System.Guid MarketingPlanItemTypeID { get; set; }
}
作成しようとしている厳密に型指定された結果は、Entity Framework コンテキストに接続する必要はありません。これが私の解決策の試みです。
public MarketingPlan GetMarketingPlanWithItems(Guid marketingPlanID)
{
var query =
this.Context
.MarketingPlanItems
.GroupJoin(this.Context.MarketingPlanItemTypes,
mpi => mpi.MarketingPlanItemTypeID,
mpit => mpit.MarketingPlanItemTypeID,
(mpi, mpit) =>
{
mpi.MarketingPlanItemType = mpit.FirstOrDefault();
return mpi;
})
.GroupJoin(this.Context.EmailTemplates,
mpi => mpi.EmailTemplateID,
et => et.EmailTemplateID,
(mpi, et) =>
{
mpi.EmailTemplate = et.FirstOrDefault();
return mpi;
})
.Where(mpi => mpi.Disabled == false);
var result =
this.Context
.MarketingPlans
.GroupJoin(query,
mp => mp.MarketingPlanID,
mpi => mpi.MarketingPlanID,
(mp, mpi) =>
{
mp.MarketingPlanItems = mpi.ToList();
return mp;
})
.Where(mp => mp.MarketingPlanID == marketingPlanID)
.FirstOrDefault();
return result;
}
GroupJoin
次のエラーがスローされるため、実際の匿名関数を使用できないことに気付きました。
ステートメント本体を含むラムダ式は式ツリーに変換できません
この例では、このようにコーディングしました。これはnew
、厳密に型指定されたオブジェクトの場合、すべてのフィールドにデータを入力する必要があると思われるためです。
最終結果は持つことです。でMarketingPlan
はMarketingPlanItems
ないものだけが取り込まれ、EmailTemplate または Null によって取り込まれ、各 MarketingPlanItem にそれが取り込まれDisable
ます。このための sql は (おおまかに) 次のようになります。EmailTemplate
MarketingPlanItemType
SELECT
mp.*,
mpi.*,
mpit.*,
et.*
FROM
MarketingPlan mp
LEFT JOIN MarketingPlanItem mpi
on mp.MarketingPlanID = mpi.MarketingPlanID
INNER JOIN MarketingPlanItemType mpit
on mpi.MarketingPlanItemTypeID = mpit.MarketingPlanItemTypeID
LEFT JOIN EmailTemplate et
on mpi.EmailTemplateID = et.EmailTemplateID
データベースに複数のリクエストを行うことなく、Lambda を使用して Entity Framework でこれを達成する方法はありますか?
更新 1
public MarketingPlan GetMarketingPlanWithItems(Guid marketingPlanID)
{
MarketingPlan result = null;
var query = this.Context.MarketingPlanItems
.Include("MarketingPlan")
.Include("MarketingPlanItemType")
.Include("EmailTemplate")
.Include("EmailTemplate.EmailTemplateCategory")
.Where(mp => !mp.Disabled
&& !mp.MarketingPlan.Disabled
&& mp.MarketingPlanID == marketingPlanID)
.ToList();
var query2 = query.FirstOrDefault();
if (query2 != null)
{
result = query2.MarketingPlan;
result.MarketingPlanItems = query;
}
return result;
}
これにより、最終的に必要なものが返されました。