【问题标题】:Entity Framework - DRY Queries实体框架 - DRY 查询
【发布时间】:2014-02-24 20:54:00
【问题描述】:

我有一个实体框架域模型(首先使用代码),其上下文包括客户,每个客户可以有多个地址,每个地址都有一个“日历范围”的日期。我可以写一个查询,例如:

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;

同样,没问题,我得到了客户信息和当前邮寄地址,查询在 SQL 中执行。

现在我想排除用于查找邮寄地址的查询。我不想在每次需要获取邮寄地址的电话中重复它。理想情况下,我想将它添加到我的域对象 Customer 中,以便查找邮寄地址的逻辑是我的 Customer 对象的一部分。

我想在我的客户对象中放置这样的方法:

public partial class Customer 
{
    public Address MailingAddress
    {
        get
        {
           return (from a in this.Addresses.AsQueryable()
               where a.AddressStartDate > DateTime.Now && 
                   a.AddressEndDate < DateTime.Now
               select a).Single()
        }
    }
}

现在我的域模型中有该属性,我想运行一个查询:

var query = from c in context.Customers
    where customerId == 1
    select new 
    {
        FirstName = c.FirstName,
        Address = c.MailingAddress
    }

不幸的是,这不适用于错误“仅支持初始化程序、实体成员和实体导航属性。”我理解这个错误,以及为什么我不能那样做。我也知道,如果我先检索客户,然后在我有客户实例后调用 MailingAddress 属性,我的方法实际上会起作用,但这会使数据库调用加倍。

如何使用 Entity Framework 保持 DRY?我需要集中“获取邮件地址”要求的代码,同时还要确保在 SQL 和一个数据库操作中执行“获取邮件地址”的逻辑?

【问题讨论】:

  • 没有接受者?到目前为止,根据我在领域驱动设计方面的经验,这是一个需要使用基于实体框架的实现来解决的重要问题。我发现了一些 linqkit 可能会促进的提示,将进一步调查。

标签: entity-framework linq-to-entities


【解决方案1】:

我解决这个问题的一般方法是为地址设置一个导航属性,这样类就会如下所示:

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);

【讨论】:

  • 我同意在这种特殊情况下导航属性将是可行的方法,但对于其他不合适的情况,它不能回答问题。假设数据模型更复杂(实际上是这样,我设计了这种情况来简化)。在复杂的场景中,用户有多个邮寄地址,并且他们有开始/结束日期,因此正确的邮寄地址是“预定的”。现在导航属性不再可能,因为外键不可能。在这种情况下,我需要过滤日期并找到正确的地址。
  • 我更新了问题以阐明复杂性以及分解实现“查找邮寄地址”的业务逻辑以更接近现实世界场景的必要性。
猜你喜欢
  • 1970-01-01
  • 2021-12-25
  • 2013-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-06
  • 2016-09-20
相关资源
最近更新 更多