C# Linq到Sql的工作单元模式与事务范围?
我想模仿DDD中广泛使用的存储库方法,在我的门户应用程序中使用Linq-2-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 =
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的特定实现的伪代码,以便以后可以将其更改为不同的实现?