实体框架 - DRY查询

时间:2014-01-31 23:59:29

标签: 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 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对象的一部分。

我想在我的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
    }

不幸的是,这不适用于错误'仅支持初始值设定项,实体成员和实体导航属性。'我理解错误,以及为什么我不能这样做。我也知道,如果我首先检索Customer然后在我有一个Customer实例后调用了MailingAddress属性,那么我的方法实际上会有效,但这会使数据库调用加倍。

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

1 个答案:

答案 0 :(得分:0)

我解决这个问题的一般方法是将地址导航属性设置为类似于:

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