我想在我的门户应用程序中使用 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,但以后可以有多个,可以对当前设计做些什么来确保跨多个数据上下文的事务?
这是使用泛型包装上下文并让客户端处理它的好方法吗?
最佳答案
我肯定会创建某种集中式但外部控制的事务控制。就我个人而言,我更喜欢 UnitOfWork,因为您可以将它设计为仅与 Repository 模型相关联的抽象,而不与任何特定于实现的细节相关联。
目前,您的工作单元是特定于实现的。您的开发人员知道名为 unitOfWork 的对象实际上是 Linq2SQL 的 DataContext。知道这一点后,他们可以完全绕过存储库并使用 UnitOfWork 进行数据库调用。这样做对他们来说不是一个好主意,但他们可以这样做的事实表明需要更全面地封装更好的抽象背后的具体细节。
我会让 UnitOfWork 成为一个 token 类; token 只是一个抽象的占位符,它指的是操作的原子集。在幕后,您可以使用 UnitsOfWork 来设置 DataContext 集合的键,并在该标记通过调用方法(它将作为参数传递)呈现给存储库时使用特定 UnitOfWork 的上下文。当 UnitOfWork 被外部代码丢弃时,处理 DataContext。像这样设计您的存储库意味着使用代码不需要任何实现细节的知识。如果您后来决定 Linq2SQL 不能满足您的需求并且您想切换到 NHibernate,那么更改将在 Repository 边界结束;无论 UnitOfWork 是指 DataContext 还是 ISession,您的消费代码都不会给出一个飞跃。
关于c# - Linq-To-Sql 的工作单元模式与事务范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4465327/