Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Linq到Sql的工作单元模式与事务范围?_C#_Linq To Sql_Design Patterns - Fatal编程技术网

C# Linq到Sql的工作单元模式与事务范围?

C# Linq到Sql的工作单元模式与事务范围?,c#,linq-to-sql,design-patterns,C#,Linq To Sql,Design Patterns,我想模仿DDD中广泛使用的存储库方法,在我的门户应用程序中使用Linq-2-Sql。到目前为止,我有: public class LinqToSqlDal<DC,T>: IDisposable, IRepository<T> where T: LinqEntity, new(), where DC: DataContext, new() { private DC unitOfWork =

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

     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();
              }


     }
公共类LinqToSqlDal:IDisposable,IRepository
其中T:LinqEntity,new(),
其中DC:DataContext,new()
{
专用DC unitOfWork=null;
公共LinqToSqlDal(字符串连接字符串)
{
this.unitOfWork=Activator.CreateInstance(typeof(DC),connectionString)作为DC;
}
公共LinqToSqlDal(字符串connectionString,DataLoadOptions loadOptions):此(connectionString)
{
this.unitOfWork.LoadOptions=LoadOptions;
}
公共虚拟无效提交更改(){
this.unitOfWork.SubmitChanges();
}
公共虚拟列表获取(表达式查询)
{
返回此.unitOfWork.GetTable().Where(查询);
}
公共虚拟作废删除(表达式查询)
{
this.unitOfWork.GetTable().DeleteAllOnSubmit(this.unitOfWork.GetTable().Where(query));
}
公共虚拟T GetByID(表达式查询)
{
返回此.unitOfWork.GetTable().Where(query.SingleOrDefault();
}
公共虚拟对象添加(T实体,字符串IDPropertyName)
{
this.unitOfWork.GetTable().InsertOnSubmit(实体);
this.SubmitChanges();
变量ID=(string.IsNullOrEmpty(IDPropertyName))?null:
entity.GetType().GetProperty(IDPropertyName).GetValue(entity,null);
返回ID;
}
公共虚拟无效提交更改()
{
this.unitOfWork.SubmitChanges();
}
公共空间处置()
{
this.unitOfWork.Dispose();
}
}
所以现在我可以将其用于该实体所属的任何实体和数据上下文。我的问题是-在这个小存储库中传递或实例化TransactionScope会有好处吗?到目前为止,我只有一个DataContext,但可以有多个DataContext。接下来,可以对当前的设计做些什么来确保跨多个数据上下文的事务


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

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

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


我会让UnitOfWork成为一个令牌类;令牌仅仅是一个抽象占位符,它引用原子操作集。在幕后,您可以使用UnitsOfWork为DataContext集合设置关键帧,并在通过调用方法将该标记呈现给存储库时使用特定UnitOfWork的上下文(它将作为参数传递)。当外部代码丢弃UnitOfWork时,请处置DataContext。这样设计存储库意味着使用代码不需要了解任何实现细节。如果您后来决定Linq2SQL不能满足您的需要,并且希望切换到NHibernate,那么更改将在存储库边界结束;无论UnitOfWork是指DataContext还是指ISession,您的消费代码都不会给出一个快速的翻转。

很好的评论,您能否提供一些关于如何开始抽象DataContext的特定实现的伪代码,以便以后可以将其更改为不同的实现?