在实体框架 6 数据库优先方法中的 DbContext 对象之间共享连接

本文关键字:DbContext 对象 之间 连接 共享 方法 框架 实体 数据库 | 更新日期: 2023-09-27 18:35:48

我正在尝试使用 EF 6 在 2 个不同的数据库上下文对象之间共享连接。我有这里提到的代码https://msdn.microsoft.com/en-us/data/dn456843.aspx适用于单个数据库上下文,但一旦我尝试与另一个数据库上下文对象共享连接,我就遇到了麻烦。以下是我这样做的目的。

public class MyUnitOfWork
{
              // BAD CODE : having static connection / transaction is bad design , i  use DI to implement  this properly without need for static fields , this code is used here to avoid having to mention my DI configuration; 
                public static EntityConnection _commonConnection ;
                public static System.Data.Entity.DbContextTransaction _commonTransaction;
                // Generic function to create DBContext object based on T supplied.
            public static T GetDbContext<T>()
            {
                 if(_commonConnection  == null)
                  {
                     // generates a generic connection string 
                        _commonConnection = new EntityConnection(DbContextBase.GenerateConnectionString()); 
                        _connection.Open();
                        _commonTransaction = _connection.BeginTransaction(System.Data.IsolationLevel.Snapshot);
                  }
                        T myContextObject = (T)Activator.CreateInstance(typeof(T), new object[1] { _connection });
                        myContextObject .Database.UseTransaction(_transaction);
                       return myContextObject;
            }
}

下面提到了用于生成连接字符串的代码:

string GenerateConnectionString()
{
            var entityBuilder = new EntityConnectionStringBuilder
            {
                Provider = "System.Data.SqlClient",                     
                ProviderConnectionString = SharedDatabase.SQLBase.DBconnection + "multipleactiveresultsets=True;" ,
                Metadata = @"res://*/;"
            };
       return entityBuilder ;
}

然后,我可以像这样从函数中的不同位置调用 GetDbContext

GetById(int id)
{
   var dbcontext = MyUnitOfWork.GetDbContext<OrdersDbContext>();
  return dbcontext.Orders.Where(.......);

}
GetCustomerInfo( int id)
{
   var dbcontext = MyUnitOfWork.GetDbContext<CustomerDbContext>();
  return dbcontext.Customer.Where(.......);
}

因为我使用的是通用元数据部分,所以我在实体框架中收到错误"无论命名空间如何,都不能有多个具有相同名称的实体"

但是,如果我指定.csdl/.ssdl文件的名称,则连接(以及事务)不能再常见,我必须为每个DBContext创建一个连接和事务(这是我想避免的)

看来我遇到了一个障碍.有没有办法让我使用相同的连接而不会收到重复实体错误?将实体名称更改为不同的对我来说不是一种选择,因为这将是一个非常耗时的更改,我必须在 30 + db 上下文/EDMX 文件中完成,并具有巨大的生产影响。

在实体框架 6 数据库优先方法中的 DbContext 对象之间共享连接

如使用事务(EF6 起)中所示,使用以下代码向上下文提供现有事务:

string GenerateConnectionString()
{
    return SharedDatabase.SQLBase.DBconnection + "multipleactiveresultsets=True;";
}

public class MyUnitOfWork
{
    SqlConnection _commonConnection;
    DbTransaction _commonTransaction;
    // Generic function to create DBContext object based on T supplied.
    public T GetDbContext<T>()
    {
        if (_commonConnection == null)
        {
            // generates a generic connection string 
            _commonConnection = new SqlConnection(DbContextBase.GenerateConnectionString());
            _commonConnection.Open();
            _commonTransaction = _connection.BeginTransaction(IsolationLevel.Snapshot);
        }
        MetadataWorkspace workspace = new MetadataWorkspace(
          string.Format("res://*/{0}.csdl|res://*/{0}.ssdl|res://*/{0}.msl;", typeof(T).Name).Split('|'), 
          new Assembly[] { Assembly.GetExecutingAssembly() });
        var connection = new EntityConnection(workspace, _commonConnection);
        T myContextObject = (T)Activator.CreateInstance(typeof(T), new object[] { connection });
        myContextObject.Database.UseTransaction(_commonTransaction);
        return myContextObject;
    }
}