将Entity Framework扩展暴露给服务层

3

我使用 IRepository 模式实现了我的数据层。其中一个方法返回一个 IQueryable

public virtual IQueryable<TEntity> Queryable()
{
        return dbSet;
}

我还有一个Service层调用了这个方法,提供筛选功能,例如:

public User GetByName(string name)
{
    return _repository.Queryable()
        .Where(a => a.Name == name)
        .ToList();
}

到目前为止,Entity Framework 仅在数据层中被引用,服务层对此一无所知。
现在,我想要做两件额外的事情:
  1. 使用 Include 方法
  2. 使用 ToListAsync() 方法
因此,我的服务方法现在如下所示:
public async Task<User> GetByName(string name)
{
    return await _repository.Queryable()
        .Where(a => a.Name == name)
        .Include(x => x.Pets)
        .ToListAsync();
}

现在的问题是Include()ToListAsync()都在System.Data.Entity命名空间中,该命名空间位于EntityFramework.dll中。
我不想在我的服务层中引用EF,因为它不应该关心或知道这一点,但我看不到其他解决方法,同时保持架构的清晰。我能想到的唯一解决方案是:
  1. 将Entity Framework添加到服务层
  2. 在数据层中添加一个新类(UserData),其包装了IRepository<User>并处理所需的两个额外方法。服务将使用此实例而不是IRepository`
有什么建议可以在遵循最佳实践的同时解决这个问题吗?

1
我真的不太明白抽象化EF的意义,如果你只是要暴露一个调用,让业务层编写自己的查询。这让存储库对我来说感觉有点毫无价值。这与问题并不相关,我只是好奇其中的逻辑是什么。 - Jonesopolis
我觉得 Include 部分应该放在仓库里面。实际上,仓库应该知道以对象图的形式返回什么,并且这些操作应该支持任何用例的业务需求。如果 ToListAsync 不是 EF 的一部分会更好,我同意这一点。虽然我猜我不太了解它的实现,不知道它是否有可能在 EF 之外存在。 - David
除了“最佳实践”之外,您为什么要使用存储库?这是出于什么原因?也许您希望缓存结果或其他一些原因。 - Evk
每当暴露IQueryable时,你都会强制API的使用者对实现有着深入的了解。你不妨添加一个EF的引用。 - Gert Arnold
即使有人提供了一个好的阅读链接,我仍然希望能够得到更新。因为我发现自己总是在不知道该做什么之间犹豫不决。 - Seabizkit
2个回答

1
我知道你想在存储库层面上抽象EF,以符合最佳实践。但是你的用例(你的主要问题)与此相矛盾 - 你想向服务层公开EF提供的所有内容。
看起来你需要明确定义这个存储库的职责边界。如果它的作用是返回一个,那么包装EF有什么好处呢?你是否计划在实际生产中使用其他存储库实现?如果是这样,当你暴露时,确保两种存储库类型都正确将非常困难。这就是你现在遇到的痛点。
在我看来,存储库应该定义如何获取数据。它应该公开简单的调用,比如GetAllUsers,返回实际的模型。当你让业务/服务层定义自己的获取数据方式时,会让存储库感觉多余。

0

Include和ToListAsync存在于EF中,因此它们应该保留在EF服务中。

如果不想提供对System.Entity的引用,唯一的访问方式是创建自己的代理方法。最终,您应该根据应用程序在高层次上所需的内容编写代码,而不是确保它可以访问EF的所有内容。

当我处理EF时,我会创建一个服务/上下文层、一个存储库层,然后是一个客户端层,它抽象了EF的技术细节。然后其他开发人员/用户使用它,以便他们不会暴露太多EF方面的内容。我只需要确定应用程序所需的内容,并实现相应的方法,而不需要更多的东西。将System.Entity的功能带到DAL之外几乎没有意义,它们应该在客户端层面进行抽象。

但有一件事我很讨厌,那就是如果我想将服务/上下文层与应用程序的其他部分隔离开来,就必须复制模型。为了解决这个问题,我有一个模型工厂,它使用DI查找EF模型,并通过DI容器传递它们。这意味着我只需要为我创建的每个模型添加一个接口即可。没什么大不了的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接