0

Data Repository,它处理从通用接口继承的数据实体,DAL 层被实现为通用类,它以依赖注入的形式获取通用接口。以下是设计:

数据实体 - 车辆

public class Vehicle
{
    public int Id {get; set;}

    public string Brand {get; set;}
}

通用接口 - IData

public interface IData<T>
{
   IEnumerable<T> Select(IDictionary<string,object> parameters);

   int Update(IDictionary<string,object> parameters);

   int Delete(IDictionary<string,object> parameters);

   int insert(IDictionary<string,object> parameters);
}

车辆存储库

public class VehicleData : IData<Vehicle>
{
   IEnumerable<Vehicle> Select(IDictionary<string,object> parameters)
   {
      using(IDbConnection conn = (Fetch Connection))
      {
         // Select Operation
      } 
   }

   int Update(IDictionary<string,object> parameters)
    {
      using(IDbConnection conn = (Fetch Connection))
      {
         // Update Operation
      } 
   }

   int Delete(IDictionary<string,object> parameters)
    {
      using(IDbConnection conn = (Fetch Connection))
      {
         // Delete Operation
      } 
   }

   int insert(IDictionary<string,object> parameters)
    {
      using(IDbConnection conn = (Fetch Connection))
      {
         // Insert Operation
      } 
   }
}

DAL 类实现:

public class DAL<T>
{
  public static IEnumerable<T> Select(IData<T> dataRepository, IDictionary<string,object> parameters)
   {
       return dataRepository.Select(parameters);
   }

// Implementation for Insert, Update and Delete
}

我从调用类执行VehicleData使用DAL如下。

IData<Vehicle> vehicleData = new VehicleData();

IDictionary<string,object> parameters = // Filled from client

DAL<Vehicle>.Select(vehicleData,parameters);

我面临的问题是,在每个 CRUD 方法中,IDbConnection 都是在Using块中创建的,因此最终被设置为它在本地上下文中,但是有一种情况,各种实体上的多个 DAL 操作需要成为单个事务上下文的一部分,如果我以类似的方式继续,那么打开的事务上下文将被提升到分布式级别,因为多个连接资源正在打开,即使我可以在相同的连接上下文上执行它们,因为它们被一一执行。问题仍然存在:

  1. 如何跨多个调用共享连接DAL<Vehicle>.Update, DAL<Driver>.Update and DAL<Truck>.Update,避免事务从本地升级到分布式

  2. 不确定,在事务上下文中打开和处理连接是否意味着可以打开另一个连接而无需提升到分布式事务,在我看来这不会发生

4

1 回答 1

1

您是否使用 IoC 容器进行依赖注入?在 IoC 中,有一些生活方式(每个线程、每个 Web 请求等)。例如,对于 Castle Windsor,您可以使用Scoped Lifestyle。你的代码将是这样的:

创建连接(linq2db):

container.Register(
    Component.For<DataConnection>().UsingFactoryMethod(x => 
        CreateDataConnection()).LifestyleScoped(),
    Component.For<IData<Vehicle>>()
        .ImplementedBy<VehicleData>().LifestyleScoped()
);

private static DataConnection CreateDataConnection()
{
    return new DataConnection(new SqlServerDataProvider("", SqlServerVersion.v2008), 
        @"Data Source=(local);Initial Catalog=DB1;Persist Security Info=True;User ID=user;Password=pwd");
}

做一些数据库操作:

using (container.BeginScope())
{
    var db = container.Resolve<DataConnection>();
    db.BeginTransaction();
    container.Resolve<IData<Vehicle>>().Update(...);
    container.Resolve<IData<Vehicle>>().Update(...);
    container.Resolve<IData<Vehicle>>().Update(...);
    db.CommitTransaction();
}
于 2016-01-21T12:10:37.193 回答