存储库模式:每个实体一个存储库类?

发布于 2024-09-15 07:43:01 字数 312 浏览 5 评论 0原文

假设您在 LINQ 类中定义了以下实体:

Product
Customer
Category

我应该为所有实体创建一个存储库类:

StoreRepository

... 还是应该:

ProductRepository
CustomerRepository
CategoryRepository

优点和优点是什么?每个的缺点?就我而言,我的解决方案中有几个“应用程序”......商店应用程序只是其中之一。

Say you have the following entities defined in a LINQ class:

Product
Customer
Category

Should I have one repository class for all:

StoreRepository

... or should I have:

ProductRepository
CustomerRepository
CategoryRepository

What are the pro & cons of each? In my case, I have several "applications" within my solution... the Store application is just one of them.

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

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

发布评论

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

评论(4

肥爪爪 2024-09-22 07:43:01

这是我的观点。我是存储库模式的严格追随者。应该有 3 个采用单个实体的方法。添加、更新、删除,一般定义。

public interface IRepository<T>
{
     void Add(T entity);
     void Update(T entity);
     void Delete(T entity);
}

除了这些方法之外,您还要处理“查询”或服务方法。如果我是您,我会按照上面的方式一般定义存储库,添加一个“QueryProvider”(如下所示),然后将您的业务逻辑放在它所属的位置在“服务”或“命令/查询”(来自 CQRS、Google it)

public interface IQueryProvider<T>
{
     TResult Query<TResult>(Func<IQueryable<T>, TResult> query);
}

(希望我的意见有点用:))

Here's my point of view. I'm a strict follower of the Repository pattern. There should be 3 methods that take a single entity. Add, Update, Delete, generically defined.

public interface IRepository<T>
{
     void Add(T entity);
     void Update(T entity);
     void Delete(T entity);
}

Beyond those methods, you're dealing with a "Query" or a service method. If I were you, I'd make the repository genrically defined as above, add a "QueryProvider" as shown below and put your business logic where it belongs in either "Services" or in "Commands/Queries" (comes from CQRS, Google it).

public interface IQueryProvider<T>
{
     TResult Query<TResult>(Func<IQueryable<T>, TResult> query);
}

(Hope my opinion is somewhat useful :) )

呆橘 2024-09-22 07:43:01

这一切都取决于您将如何实现“领域驱动设计”。你知道什么是聚合根吗?大多数时候,一般输入 with 就可以完成所有基本的 CRUD 操作就足够了。只有当您开始拥有具有上下文和边界的厚模型时,这一点才开始变得重要。

This all depends on how "Domain Driven Design" your going to be. Do you know what an Aggregate Root is? Most of the time a generically typed on with can do all your basic CRUD will suffice. Its only when you start having thick models with context and boundaries that this starts to matter.

无尽的现实 2024-09-22 07:43:01

基本上,每个聚合根对象都会有一个存储库。书中有一些关于 DDD 和聚合根对象以及我们应该如何设计存储库类的有趣观点 ASP.NET MVC 2 in Action,如果您想了解更多信息,请查看它。

Basically there will be one repository per aggregate root object. There are some interesting points about DDD and aggregate root object and how we should design repository classes in the book ASP.NET MVC 2 in Action, look at it if you want to know more.

久而酒知 2024-09-22 07:43:01

我有一个存储库/对象,因为总是需要有一个从我的 EntityTable 到我的域对象的映射(例如在 GetIQueryableCollection() 的主体中)。我如何编写这个重复的代码是通过制作一个T4 模板为我生成它。

我有一个示例项目,它在 codeplex http://t4tarantino.codeplex.com/ T4 上生成存储库模式工具箱示例 业务类和存储库的模板。
如果不进行一些调整,它可能无法完全按照您想要的方式工作,除非您已经实现了 Tarintino 和其他一些好东西,但模板很容易配置。

using System;
using System.Collections.Generic;
using System.Linq;
using Cses.Core.Domain.Model;
using StructureMap;

namespace Cses.Core.Domain
{
    /// <summary>
    /// Core class for Schedule E
    /// </summary>
    public class ScheduleERepository : IScheduleERepository
    {

        private Cses.Core.Repository.SqlDataContext _context = new Cses.Core.Repository.SqlDataContext();

        /// <summary>
        /// constructor
        /// </summary>
        public ScheduleERepository() { }

        /// <summary>
        /// constructor for testing
        /// </summary>
        /// <param name="context"></param>
        public ScheduleERepository(Cses.Core.Repository.SqlDataContext context)
        {
            _context = context;

        }

        /// <summary>
        /// returns collection of scheduleE values
        /// </summary>
        /// <returns></returns>
        public IQueryable<ScheduleE> GetIQueryableCollection()
        {           
            return from entity in _context.ScheduleEs                  
               select new ScheduleE()
               {    
                    Amount = entity.Amount,
                    NumberOfChildren = entity.NumberChildren,
                    EffectiveDate = entity.EffectiveDate,
                    MonthlyIncome = entity.MonthlyIncome,
                    ModifiedDate = entity.ModifiedDate,
                    ModifiedBy = entity.ModifiedBy,                      
                    Id = entity.Id                          
               };           
        }

I'd have one repository/object because invariably, there'd need to be a map from my EntityTable to my domain object (such as in the body of the GetIQueryableCollection(). How I got around writing this repetitive code is by making a T4 template to generate it for me.

I have an example project which generates the repository pattern on codeplex http://t4tarantino.codeplex.com/ T4 Toolbox example Templates for business classes and repository.
It may not work exactly the way you'd like without some tweaking, unless you're already implementing Tarintino and a few other goodies, but the templates are easy to configure.

using System;
using System.Collections.Generic;
using System.Linq;
using Cses.Core.Domain.Model;
using StructureMap;

namespace Cses.Core.Domain
{
    /// <summary>
    /// Core class for Schedule E
    /// </summary>
    public class ScheduleERepository : IScheduleERepository
    {

        private Cses.Core.Repository.SqlDataContext _context = new Cses.Core.Repository.SqlDataContext();

        /// <summary>
        /// constructor
        /// </summary>
        public ScheduleERepository() { }

        /// <summary>
        /// constructor for testing
        /// </summary>
        /// <param name="context"></param>
        public ScheduleERepository(Cses.Core.Repository.SqlDataContext context)
        {
            _context = context;

        }

        /// <summary>
        /// returns collection of scheduleE values
        /// </summary>
        /// <returns></returns>
        public IQueryable<ScheduleE> GetIQueryableCollection()
        {           
            return from entity in _context.ScheduleEs                  
               select new ScheduleE()
               {    
                    Amount = entity.Amount,
                    NumberOfChildren = entity.NumberChildren,
                    EffectiveDate = entity.EffectiveDate,
                    MonthlyIncome = entity.MonthlyIncome,
                    ModifiedDate = entity.ModifiedDate,
                    ModifiedBy = entity.ModifiedBy,                      
                    Id = entity.Id                          
               };           
        }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文