如何使用存储库模式处理表关系?

发布于 2024-11-06 09:32:37 字数 855 浏览 0 评论 0原文

我正在将存储库模式实现为 ASP.NET MVC 站点的一部分。我见过的大多数存储库示例都相当简单。例如,这是一个典型的抽象存储库接口。

public interface IRepository<TEntity>
{
    IQueryable<TEntity> All();
    TEntity FindBy(int id);
    TEntity FindBy(Expression<Func<TEntity, bool>> expression);
    IQueryable<TEntity> FilterBy(Expression<Func<TEntity, bool>> expression);
    bool Add(TEntity entity);
    bool Update(TEntity entity);
    bool Delete(TEntity entity):
}

我很清楚如何使用这样的存储库来添加、更新、删除或获取单一类型的实体。但是如何处理创建和操作不同类型之间的一对多或多对多关系呢?

假设您有一个 Item 类型,其中每个项目都分配给一个 Category。您将如何通过存储库进行此分配?这是否应该由 Update(Category c) 和/或 Update(Item i) 方法来确定需要与正在更新的元素建立什么关系?或者应该有一个显式的 AssignCategoryToItem(Item i, Category c) 方法?

如果有什么区别的话,我会使用 Fluent NHibernate 来实现我的具体存储库。

I'm implementing the repository pattern as part of an ASP.NET MVC site. Most examples I've seen of repositories are fairly simple. For example here's a typical abstract repository interface.

public interface IRepository<TEntity>
{
    IQueryable<TEntity> All();
    TEntity FindBy(int id);
    TEntity FindBy(Expression<Func<TEntity, bool>> expression);
    IQueryable<TEntity> FilterBy(Expression<Func<TEntity, bool>> expression);
    bool Add(TEntity entity);
    bool Update(TEntity entity);
    bool Delete(TEntity entity):
}

It's clear to me how you would use a repository like this to add, update, delete, or get entities of a single type. But how do you handle creating and manipulating one-to-many or many-to-many relationships between different types?

Say you have an Item type where each item is assigned to a Category. How would you make this assignment through the repository? Should this be up to the Update(Category c) and/or Update(Item i) methods to figure out what relationships need to be made to or from the element being updated? Or should there be an explicit AssignCategoryToItem(Item i, Category c) method?

If it makes any difference I'm using Fluent NHibernate to implement my concrete repositories.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

怪我太投入 2024-11-13 09:32:37

您的应用程序如何处理为项目分配类别?

执行以下操作:

  1. 允许用户查看该项目,然后为其分配一个类别
  2. 允许用户查看该类别,然后向其中添加项目

让您的应用程序决定您选择哪种方法。

这就提出了拥有业务逻辑/服务层并处理<的想法强>聚合根。在我的应用程序中,我总是有一个服务层,所有业务逻辑都位于其中。我发现这样做使我的应用程序更易于理解和维护/重构。 (注意:我还使用通用存储库,并将复杂的存储库查找放在适当服务类中的单独函数中)

在您的 services 层中,您将有一个名为 AssignCategoryToItem 然后将获取类别(聚合根),然后您将项目添加到该类别并保存更改 - 尽管我更喜欢传递以下的 ID类别并将其从更新前的数据库。

How does your app handle assigning a category to an item?

Does it:

  1. Allows the user to view the item then assign it a category
  2. Allows the user to view the category then add items to it

Let your app dictate which method you pick.

This brings up the idea of having a Business Logic/Services layer and dealing with aggregate roots. In my applications, I always have a services layer where all the business logic is at. I found that doing this has made my application easier to understand and maintain/refactor. (Note: I also use generic repositories and put the complex repository look ups in separate functions in the proper service class)

In your services layer, you'll have a function called AssignCategoryToItem which would then take the category (the aggregate root) and you would then add the item to that category and save the changes - although I would prefer passing in the IDs of the category and pulling it from the database before updating.

与之呼应 2024-11-13 09:32:37

一旦定义了聚合根,您应该为它们创建非常具体的存储库接口(例如 IProductRepository),并让您的服务层使用它们。

例如...

public interface IProductRepository
{
    IList<Product> GetProductsInCategory(Category c);
    Product GetProductBy(int id);
    IList<Category> GetActiveProductCategories();
}

然后在 IProductRepository 的具体实现中,您将使用通用存储库并查询相关实体并根据需要加入它们。

Once you have defined your aggregate roots you should create very specific repository interfaces (such as IProductRepository) for these, and have your service layer consume them.

Such as...

public interface IProductRepository
{
    IList<Product> GetProductsInCategory(Category c);
    Product GetProductBy(int id);
    IList<Category> GetActiveProductCategories();
}

Then in your concrete implementation of IProductRepository you would consume the generic repository and query your related entities and join them as required.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文