【发布时间】:2012-07-05 16:46:20
【问题描述】:
这是我正在使用的一组简化的表,它们被描述为类。我正在使用 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; }
}
我尝试创建的强类型结果不需要连接到实体框架上下文。这是我对解决方案的尝试。
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 中使用真正的匿名函数,因为它会引发以下错误:
带有语句体的 lambda 表达式不能转换为表达式树
我在这个例子中是这样编码的,因为如果我 new 是一个强类型对象,我相信我必须填充我不想做的每个字段。
最终的结果是有;一个MarketingPlan,其中MarketingPlanItems 仅填充不是Disable 的EmailTemplate,由EmailTemplate 或Null 填充,每个MarketingPlanItem 填充它的MarketingPlanItemType。用于此的 sql 可能看起来像(大致):
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
有没有办法在 Entity Framework 中使用 Lambda 完成此操作,而无需对数据库执行多个请求?
更新 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;
}
这最终返回了我需要的东西。
【问题讨论】:
-
那是一个真正的匿名函数。它只是不是一个单一的表达式 lambda 表达式。
-
您真的需要将结果作为新的 MarketingPlan 并在其集合中启用计划吗?我问是因为这最终会创建一个新实体。您不应该返回刚刚启用的计划,并根据需要拥有消费者组吗?
标签: c# .net entity-framework lambda