存储库模式和Linq到sql

时间:2009-10-15 16:51:05

标签: asp.net linq-to-sql repository design-patterns entities

我正在尝试使用角色表,用户表和具有userid,roleid的外部参照表来实现用户身份验证和授权。

用于实现通用repoistory更新角色,插入角色,添加用户,将用户添加到角色,更新用户,更新用户角色,验证用户,添加用户会话以进行审核等我是否为每个人编写了单独的功能或者我可以使用类似函数的一种通用方法。 还有一些其他操作,例如将用户连接到其他表并根据条件获得前5行,使用单个表单插入3个表(加入键)等

我很困惑阅读许多文章和样本,我看到的bcos样本除了CRUD操作外不会深入实现。

有人可以指导我或指导我一个好的样本/文章吗?

3 个答案:

答案 0 :(得分:7)

首先,请遵循Frank Schwieterman的说法。随着使用量的增长,让您的存储库增长。此外,了解并使用IQueryable接口。 L2S,以及实体框架,LINQ到nHibernate,以及一些新的ORM,如SubSonic和Telerik的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映射器的真正好处。

如果您更改了一种方法,您可以保留原始的简单存储库界面,但仍然可以提供很大的灵活性:

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本身的基本Repository类,允许您不再需要GetAll()调用,只需直接查询存储库(尽管有另一种复杂程度。)

答案 1 :(得分:1)

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

答案 2 :(得分:-2)

linq2sql是一个ActiveRecord模式的实现,它有点反模式,所以如果你想使用存储库模式,那么你不能使用linq2sql,而是可以将关注点分开的其他东西(实体和单独的类的单独类)用于数据访问)

或者你可能以某种方式,我不知道:D