gpt4 book ai didi

linq-to-sql - 存储库应该向服务层公开 IQueryable 还是在实现中执行过滤?

转载 作者:行者123 更新时间:2023-12-04 02:00:47 28 4
gpt4 key购买 nike

我正在尝试确定 MVC 应用程序中数据访问的最佳模式。
目前,在遵循 MVC 店面系列之后,我正在使用存储库,将 IQueryable 暴露给服务层,然后应用过滤器。最初我一直在使用 LINQtoSQL,例如

public interface IMyRepository
{
IQueryable<MyClass> GetAll();
}

实现于:
public class LINQtoSQLRepository : IMyRepository
{
public IQueryable<MyClass> GetAll()
{
return from table in dbContext.table
select new MyClass
{
Field1 = table.field1,
... etc.
}
}
}

过滤 ID:
public static class TableFilters 
{
public static MyClass WithID(this IQueryable<MyClass> qry, string id)
{
return (from t in qry
where t.ID == id
select t).SingleOrDefault();
}
}

从服务调用:
public class TableService
{
public MyClass RecordsByID(string id)
{
return _repository.GetAll()
.WithID(id);
}
}

当我尝试使用带有 LINQ to Entities 的 Entity Framework 实现存储库时,我遇到了一个问题。我的项目中的过滤器类包含一些比上面示例中的“WHERE ... == ...”更复杂的操作,我认为这需要不同的实现,具体取决于 LINQ 提供程序。具体来说,我需要执行 SQL "WHERE ... IN ..."子句。我可以使用以下方法在过滤器类中实现这一点:
string[] aParams = // array of IDs
qry = qry.Where(t => aParams.Contains(t.ID));

但是,为了针对 Entity Framework 执行此操作,我需要提供一个解决方案,例如与 Entity Framework 相关的 BuildContainsExpression。这意味着我必须有这个特定过滤器的 2 个不同实现,具体取决于底层提供程序。

我很感激我应该如何从这里开始的任何建议。
在我看来,从我的存储库中公开 IQueryable 将允许我对其执行过滤器而不管底层提供者如何,使我能够在需要时在提供者之间切换。然而,我上面描述的问题让我觉得我应该在存储库中执行所有过滤并返回 IEnumerable、IList 或单个类。

非常感谢,
马特

最佳答案

这是一个非常受欢迎的问题。一个我不断问自己的。我一直觉得最好从存储库返回 IEnumerable 而不是 IQueryable。

存储库的目的是封装数据库基础结构,因此客户端无需担心数据源。但是,如果您返回 IQueryable,您将受到消费者的支配,即会针对您的数据库运行哪种查询,以及它们是否会执行 LINQ 提供程序不支持的操作。

以分页为例。假设您有一个 Customer 实体,而您的数据库可能有数十万个客户。您希望客户编写哪些代码?

var customers = repos.GetCustomers().Skip(skipCount).Take(pageSize).ToList();

要么
var customers = repos.GetCustomers(pageIndex, pageSize);

在第一种方法中,您使存储库无法限制从数据源检索的记录数。此外,您的消费者必须计算skipCount。

在第二种方法中,您为客户端提供了更粗粒度的界面。现在您的存储库可以对 pageSize 实现一些约束以优化查询。您还封装了skipCount 的计算。

但是,话虽如此,在您的情况下,您的客户就是您的服务。所以我想这个问题真的归结为关注点的分离。在哪里执行这种验证逻辑更好?那么这个答案很可能是“在服务中”。但是“哪里更好地包含查询逻辑?”的答案呢?对我来说,答案显然是“存储库”。这是其预期的专业领域。

关于linq-to-sql - 存储库应该向服务层公开 IQueryable 还是在实现中执行过滤?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2857552/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com