Linq-To-Sql 的工作单元模式与事务范围?

发布于 2024-10-08 15:57:19 字数 2365 浏览 1 评论 0原文

我想在我的门户应用程序中使用 Linq-2-Sql 来模仿 DDD 中广泛使用的存储库方法。到目前为止我已经有了:

     public class LinqToSqlDal<DC,T>: IDisposable, IRepository<T> 
        where T: LinqEntity, new(),
        where DC: DataContext, new() 
     {

              private DC unitOfWork = null;

              public LinqToSqlDal(string connectionString) 
              {
                   this.unitOfWork = Activator.CreateInstance(typeof(DC), connectionString) as DC; 
              }

               public LinqToSqlDal(string connectionString, DataLoadOptions loadOptions): this(connectionString) 
              {
                   this.unitOfWork.LoadOptions = loadOptions;
              }

              public virtual void SubmitChanges() { 
                 this.unitOfWork.SubmitChanges();
              }

              public virtual List<T> Get(Expression<Func<T,bool>> query) 
              {
                   return this.unitOfWork.GetTable<T>().Where(query);
              }

              public virtual void Delete(Expression<Funct<T, bool>> query) 
              {
                   this.unitOfWork.GetTable<T>().DeleteAllOnSubmit(this.unitOfWork.GetTable<T>().Where(query));
              }

              public virtual T GetByID<T>(Expression<Funct<T, bool>> query) 
              {
                     return this.unitOfWork.GetTable<T>().Where(query).SingleOrDefault();
              }

              public virtual object Add(T entity, string IDPropertyName) 
              {
                this.unitOfWork.GetTable<T>().InsertOnSubmit(entity);
                this.SubmitChanges();

                 var ID = (string.IsNullOrEmpty(IDPropertyName)) ? null : 
                    entity.GetType().GetProperty(IDPropertyName).GetValue(entity, null);

                   return ID;
              }

               public virtual void SubmitChanges() 
               {
                   this.unitOfWork.SubmitChanges();
               }

              public void Dispose() 
              {
                 this.unitOfWork.Dispose();
              }


     }

所以现在我可以将它与该实体所属的任何实体和 DataContext 一起使用。我的问题是 - 在这个小存储库中传递或实例化 TransactionScope 会有好处吗?到目前为止,我只有一个 DataContext,但以后可以有多个 DataContext,可以对当前设计做些什么来确保跨多个数据上下文的事务?

这是使用泛型包装上下文并让客户端处理它的好方法吗?

I would like to mimic the Repository approach that is widely used in DDD with Linq-2-Sql in my portal app. So far I have this:

     public class LinqToSqlDal<DC,T>: IDisposable, IRepository<T> 
        where T: LinqEntity, new(),
        where DC: DataContext, new() 
     {

              private DC unitOfWork = null;

              public LinqToSqlDal(string connectionString) 
              {
                   this.unitOfWork = Activator.CreateInstance(typeof(DC), connectionString) as DC; 
              }

               public LinqToSqlDal(string connectionString, DataLoadOptions loadOptions): this(connectionString) 
              {
                   this.unitOfWork.LoadOptions = loadOptions;
              }

              public virtual void SubmitChanges() { 
                 this.unitOfWork.SubmitChanges();
              }

              public virtual List<T> Get(Expression<Func<T,bool>> query) 
              {
                   return this.unitOfWork.GetTable<T>().Where(query);
              }

              public virtual void Delete(Expression<Funct<T, bool>> query) 
              {
                   this.unitOfWork.GetTable<T>().DeleteAllOnSubmit(this.unitOfWork.GetTable<T>().Where(query));
              }

              public virtual T GetByID<T>(Expression<Funct<T, bool>> query) 
              {
                     return this.unitOfWork.GetTable<T>().Where(query).SingleOrDefault();
              }

              public virtual object Add(T entity, string IDPropertyName) 
              {
                this.unitOfWork.GetTable<T>().InsertOnSubmit(entity);
                this.SubmitChanges();

                 var ID = (string.IsNullOrEmpty(IDPropertyName)) ? null : 
                    entity.GetType().GetProperty(IDPropertyName).GetValue(entity, null);

                   return ID;
              }

               public virtual void SubmitChanges() 
               {
                   this.unitOfWork.SubmitChanges();
               }

              public void Dispose() 
              {
                 this.unitOfWork.Dispose();
              }


     }

So now I can use this with any Entity and DataContext that entity belongs to. My question is - would passing or instantiating a TransactionScope inside this little repository benefit? So far I have only one DataContext but can have multiple going forward, what can be done to the current design to ensure transactions across multiple data contexts?

Is this a good approach to wrap the context with using generics and let the clients dispose of it?

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

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

发布评论

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

评论(1

凯凯我们等你回来 2024-10-15 15:57:19

我肯定会创建某种集中但外部控制的交易控制。就我个人而言,我更喜欢 UnitOfWork,因为您可以将其设计为仅与存储库模型相关的抽象,而不与任何特定于实现的细节相关。

目前,您的工作单元是特定于实现的。您的开发人员知道名为unitOfWork 的对象实际上是Linq2SQL 的DataContext。知道这一点后,他们可以完全绕过存储库并使用 UnitOfWork 进行数据库调用。对他们来说这样做是一个坏主意,但事实上他们可以表明需要更全面地将具体细节封装在更好的摘要背后。

我将使 UnitOfWork 成为一个令牌类;令牌只是一个抽象占位符,引用原子操作集。在幕后,您可以使用 UnitsOfWork 来设置 DataContext 集合的键,并在每当通过调用方法将该令牌呈现给存储库(它将作为参数传递)时使用特定 UnitOfWork 的 Context。当 UnitOfWork 被外部代码丢弃时,处理 DataContext。像这样设计存储库意味着使用代码不需要任何实现细节的知识。如果您后来发现 Linq2SQL 不能满足您的需求并且想要切换到 NHibernate,则更改将在存储库边界结束;无论 UnitOfWork 引用的是 DataContext 还是 ISession,您的消费代码都不会发生飞跃。

I would definitely create some sort of centralized but externally-controlled transaction control. Personally, I favor UnitOfWork, because you can design it to be an abstract that is tied only to the Repository model and not to any implementation-specific details.

Currently, your unit of work is implementation-specific. Your developers know that the object named unitOfWork is actually a DataContext for Linq2SQL. Knowing that, they can bypass the Repository completely and use a UnitOfWork to make their DB calls. It would be a bad idea for them to do so, but the fact they can suggests a need to more fully encapsulate the specific details behind a better abstract.

I would make UnitOfWork a token class; the token is merely an abstract placeholder that refers to the atomic set of operations. Behind the scenes, you can use UnitsOfWork to key a collection of DataContexts, and use the Context for a particular UnitOfWork whenever that token is presented to the Repository by a calling method (it would be passed as a parameter). When the UnitOfWork is discarded by external code, dispose of the DataContext. Designing your Repository like this means that consuming code does not require any knowledge of the implementation details. If you later decide that Linq2SQL isn't meeting your needs and you want to switch to NHibernate, the changes end at the Repository boundary; your consuming code doesn't give a flying flip whether the UnitOfWork refers to a DataContext or an ISession.

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