仓储模式和Linq to sql (注意:这是一个标题,不需要回答)

3

我正在尝试使用角色表、用户表和具有userid、roleid的xref表来实现用户身份验证和授权。

为了实现通用存储库以更新角色、插入角色、添加用户、将用户添加到角色、更新用户、更新用户角色、验证用户、将用户会话添加到审计等,我是否需要为每个功能编写单独的函数,还是可以使用一个通用方法来处理类似的功能。还有一些其他操作,例如将用户加入其他表并基于条件获取前5行,在单个表单中插入3个表(连接到一个键)等。

我阅读了许多文章和示例,感到很困惑,因为我看到的示例除了CRUD操作之外没有深入的实现。

能否有人指导我或将我引导到一个好的示例/文章?

3个回答

7
首先,遵循Frank Schwieterman所说的。让你的存储库随着它们的使用而增长。此外,了解并利用IQueryable接口。 L2S以及Entity Framework,LINQ to nHibernate和一些新的ORM(如SubSonic和Telerik's ORM)都支持IQueryable接口。
在需要可变查询但仍希望获得必要的OR映射器互换好处的情况下,IQueryable是一个强大的工具。假设像以下这样的东西:
public class ProductRepository: IProductRepository
{
    public Product GetByID(int id);
    public IList<Product> GetAll();
    public void Insert(Product product);
    public Product Update(Product product);
    public void Delete(Product product);
}

这是一个非常常见的存储库,具有基本的通用方法。随着时间的推移,您可能会拥有更多的方法:

public IList<Product> GetByOrder(Order order);
public IList<Product> GetByCategory(Category category);
public IList<Product> GetByQuantityInStock(int quantityInStock);

这也是相当普遍的情况,根据你喜欢解决问题的方式,它是完全可以接受的。然而,从长远来看,你的代码库可能会变得难以控制,并且其接口将始终在变化。你还会失去使用OR mapper的真正好处。
如果你改变一个方法,你可以保持原始简单的代码库接口,但仍然为自己提供很多灵活性:
public IQueryable<Product> GetAll();

您的代码库现在返回一个查询而不是已检索对象的列表。现在您可以像使用任何其他LINQ启用的对象一样使用此查询:

var productsWithLowStock = productRepository.GetAll().Where(p => p.Quantity < 10);

var orders = orderRepository.GetAll();
var productsWithOrders = productRepository.GetAll().Where(p => orders.OrderLines.Any(ol => ol.ProductID == p.ProductID));

一旦您开始使用IQueryable接口与您的仓储库一起,您将获得最佳效果:在较低级别的数据访问周围具有可模拟抽象,并且可以在代码中动态查询的能力。您可以将此概念推广一步,并创建一个基础仓储库类,它实现了IQueryable本身,允许您消除GetAll()调用的需要,并直接查询存储库(尽管有另一种复杂程度)。


使用这种方法可能会遇到一个问题,那就是何时调用dispose。因此,我通常有两个存储库接口,一个具有此IQueryable<Row>类型访问器(支持IDisposeable并且其生命周期必须由调用方管理),另一个用于写入或其他复杂操作,在其中每个调用内部使用一个数据上下文。 - Frank Schwieterman

1
理想情况下,您不应该猜测存储库的要求。一种方法是先编写使用存储库的代码,根据需要扩展存储库的接口。如果编写单元测试为存储库提供测试替身,则可以实现此目标。

-2

linq2sql是ActiveRecord模式的一种实现,但这种模式有点反模式,所以如果你想使用仓储模式,那么就不能使用linq2sql,而是要使用其他可以实现关注点分离(实体类和数据访问分别在不同的类中)的东西。

或者可能你可以想出其他办法,我也不太清楚:D


1
使用存储库模式与L2S绝对是可行的。 L2S还支持POCO设计,通过映射和通用DataContext方法,使您能够将域类型与持久性问题解耦。 L2S的主要限制是支持的映射种类有限...通常只支持1对1的数据库表。但这当然不排除使用存储库的可能性。 - jrista
酷,你能给我一个链接吗?展示如何使用Linq2SQL或Castle ActiveRecord或Subsonic等实现存储库模式的内容。 - Omu

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