【问题标题】:How to create a Generic Repository a 'deep include'?如何创建一个“深度包含”的通用存储库?
【发布时间】:2012-03-02 14:51:21
【问题描述】:

我在 EF Codefirst 之上创建了一个包含一些方法的通用存储库,效果很好。 Get 方法看起来像这样(这包括一层)

public virtual IEnumerable<T> Get(
        Expression<Func<T, bool>> filter = null,
        Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null,
        string includeProperties = "") 
{

        IQueryable<T> query = _dDbSet;

        if (filter != null)
            query = query.Where(filter);

        query = includeProperties.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Aggregate(query, (current, includeProperty) => current.Include(includeProperty));

        return orderBy != null ? orderBy(query).ToList() : query.ToList();
    }

但是当我需要通用存储库返回“更深”的包含时,我偶然发现了一个问题

一个例子:Hotel 对象与房间列表有关系,每个房间都与人有关系。

我希望我的方法返回一个 Hotel 对象,其中包含与这些房间相关的人员的房间列表。

如何使用 GenericRepository 解决这个问题?

我不想使用解决方案:

    var hotel = _hotelRepository.Context.Hotels.Where(p => p.HotelId == HotelId).Include(p => p.RoomList.Select(b => b.Person)).First();

在我的业务类中,因为我想分离出对 genericRepository 的数据访问,并能够在我的测试项目中模拟出该方法。

是否有一个好的解决方案,或者我必须使用上面提到的 Select 上下文?

谢谢!

【问题讨论】:

    标签: c# linq repository ef-code-first


    【解决方案1】:

    我闻到了Inner-Platform Effect。您正试图让您的通用存储库完成 EF 所做的一切。为什么不直接使用 EF(或您使用的任何 ORM)?

    就个人而言,我不久前放弃了自己的存储库。我通过在“报告”类中直接使用 ORM 来封装可重用的查询。对于更简单的一次性查询,我直接使用 ORM。当我编写报表类或直接查询时,我知道要包含/急切地获取什么等,并且可以使用 ORM 提供的工具。

    记住:你的 ORM 已经存储库,不需要包装它(IMO)。

    http://ayende.com/blog/3955/repository-is-the-new-singleton

    【讨论】:

    • 是的,我明白了,我尽量让我的存储库尽可能小。但我越来越多地看到我的存储库可能需要一种新方法来使用“更深”的包含进行提取。我可能从错误的角度思考这个问题。我直接使用 ORM 没有问题,就像我最初问题中的 Select 语句一样。但是比 GenericRepository.Get() 更难模拟所有不同的 context.hotel.where(h => h.id == etc)。
    • 我知道存储库很容易模拟,因此非常适合测试。但即使没有存储库,您也可以选择:1)设置一个内存数据库(SQLite)进行测试。是的,它不再是 100% 独立的单元测试。 2) 将调用 ORM 的部分移动到虚拟方法中,创建派生类,覆盖这些方法并注入测试值(基本上应用 template method pattern)。 3)对于复杂的查询,将它们隔离在单独的类中,您可以在测试中为其注入 fakes/mocks/stubs。
    猜你喜欢
    • 2021-10-05
    • 1970-01-01
    • 1970-01-01
    • 2021-04-18
    • 1970-01-01
    • 2022-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多