【问题标题】:Strongly Typed Repository Return Types强类型存储库返回类型
【发布时间】:2016-04-12 00:25:27
【问题描述】:

所以我最近在 Entity Framework 6 中进行了大量编程,我对急切加载的某些行为感到相当恼火。

拿着这个:

var customers = _db.Customers.Where(c => c.IsActive);
var customersWithOrders = _db.Customers.Include(c => c.Orders).Where(c => c.IsActive);

customers.SelectMany(c => c.Orders).DoSomething(...); // NRE
customers.SelectMany(c => c.Orders).DoSomething(...); // Works

我知道我实际上可以在 EF 中启用延迟加载,但我想避免这样做,因为它只会将其变成 Select N+1 问题。

我不喜欢这两个查询实际上返回不同类型的数据,即使它们的签名本质上是 IEnumerable<Customer> 如果我要在 EF 之上编写自己的存储库,我更愿意这样做像这样:

public class CustomerRepo {
    IEnumerable<T> GetCertainCustomers<T>(...);
    IEnumerable<T> DifferentCustomerQuery<T>(...);
    IEnumerable<T> YetAnotherQuery<T>(...);
}

public class Customer {...}
public class CustomerWithOrders : Customer { public IEnumerable<Order> Orders { get; set;} }
public class CustomerWithPaymentMethods : Customer { public IEnumerable<Order> Orders { get; set;} }

类似上面的东西实际上可以正常工作,存储库在给定类型参数 T 的情况下执行正确数量的急切加载。

我的问题是,如果你有超过 2-3 个不同的急切加载选项,类型的数量将会激增,更不用说当你想急切加载多个关系时会发生什么!

仅供参考,以上所有代码仅用于说明,并非真实。

【问题讨论】:

  • 我不明白您要解决什么问题。如果您不想创建专门的类型,请不要创建它们。 Table Per HierarchyTable-Per-Type 都可以根据您的特定要求工作得相当好,并且是众所周知的既定模式。可以更详细地解释您要解决的问题吗?
  • 特别是什么是“NRE”?哪两个查询返回不同类型的数据,为什么类型不同?究竟什么是“正确的急切加载量”?与您的存储库类/方法接受的类型相反,您编写的 EF 查询不是预先加载的吗?

标签: c# .net entity-framework orm repository


【解决方案1】:

如果您担心空引用异常特别是,您可以简单地默认为您的Orders 提供一个空集合。

例如:

public class Customer
{
    public virtual List<Order> Orders { get; set; }
    public Customer()
    {
        Orders = new List<Order>();
    }
}

加载没有.Include(c =&gt; c.Order) 的客户意味着集合将保持,但不会null。这意味着您的示例:

customers.SelectMany(c => c.Orders).DoSomething(...);
customersWithOrders.SelectMany(c => c.Orders).DoSomething(...);

两者都可以工作(第一个什么都不做,因为集合是空的)。

在任何情况下,您应该在适当的时候进行空值检查。如果您的方法需要有订单的客户,它应该检查。定义一个仅描述对象中哪些信息为空或不为空的类是一个坏主意。

【讨论】:

    猜你喜欢
    • 2023-04-09
    • 2011-04-30
    • 2018-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多