Entity framework 实体框架-干查询
我有一个实体框架域模型(首先使用代码),其上下文包括客户,每个客户可以有多个地址,每个地址上都有日期的“日历范围”。我可以编写一个查询,例如:Entity framework 实体框架-干查询,entity-framework,linq-to-entities,Entity Framework,Linq To Entities,我有一个实体框架域模型(首先使用代码),其上下文包括客户,每个客户可以有多个地址,每个地址上都有日期的“日历范围”。我可以编写一个查询,例如: var query = from c in context.Customers where c.CustomerId == 1 select c Customer cust = query.Single(); 生成的客户是我通过Where子句选择的客户。没问题。现在,我还想获取他们查看的邮寄地址,因此我会: var query = from c in
var query = from c in context.Customers
where c.CustomerId == 1
select c
Customer cust = query.Single();
生成的客户是我通过Where子句选择的客户。没问题。现在,我还想获取他们查看的邮寄地址,因此我会:
var query = from c in context.Customers
where c.CustomerId == 1
select new
{
FirstName = c.FirstName,
Address = c.Addresses.Where(a => a.AddressStartDate > DateTime.Now &&
a.AddressEndDate < DateTime.Now)
}
var data = query.Single();
Address MailingAddress = data.Address;
不幸的是,这不适用于错误“仅支持初始值设定项、实体成员和实体导航属性”。我理解错误,以及为什么我不能这样做。我还知道,如果我先检索客户,然后在拥有客户实例后调用MailingAddress属性,那么我的方法实际上会起作用,但这会使数据库调用加倍
如何使用实体框架保持干燥?我需要集中“获取邮件地址”要求的代码,同时确保在SQL和一个db操作中执行“获取邮件地址”的逻辑?解决此问题的一般方法是使用指向地址的导航属性,这样类看起来像:
public class Customer
{
public int Id { get; set; }
public int MailingAddressId { get; set; }
[ForeignKey("MailingAddressId")]
public virtual Address MailingAddress { get; set; }
public ICollection<Address> Addresses { get; set; }
}
我同意导航属性在这种特殊情况下是可行的,但对于其他不合适的情况,它不能回答这个问题。让我们假设数据模型更复杂(事实上是这样的,我设计这种情况是为了简化)。在复杂的场景中,用户有多个邮件地址,并且他们有开始/结束日期,因此正确的邮件地址是“预定的”。现在导航属性不再可用,因为无法使用外键。在这种情况下,我需要按日期筛选并找到合适的地址。我更新了问题,以澄清实现“查找邮寄地址”的业务逻辑的复杂性和必要性,以便更紧密地与现实世界的场景保持一致。没有接受者吗?到目前为止,根据我在领域驱动设计方面的经验,这是一个需要通过基于实体框架的实现来解决的重要问题。我发现了一些linqkit可能有助于进一步研究的提示。
var query = from c in context.Customers
where customerId == 1
select new
{
FirstName = c.FirstName,
Address = c.MailingAddress
}
public class Customer
{
public int Id { get; set; }
public int MailingAddressId { get; set; }
[ForeignKey("MailingAddressId")]
public virtual Address MailingAddress { get; set; }
public ICollection<Address> Addresses { get; set; }
}
var customer = context.Customer.Include("MailingAddress").FirstOrDefault(c => c.Id = 1);