Asp.net mvc 实体框架、Unity和MVC
我有一个使用实体框架、MVC和Unity的多层应用程序。 基本设置如下所示: EF数据访问层Asp.net mvc 实体框架、Unity和MVC,asp.net-mvc,entity-framework,unity-container,Asp.net Mvc,Entity Framework,Unity Container,我有一个使用实体框架、MVC和Unity的多层应用程序。 基本设置如下所示: EF数据访问层 public class MyDataProvider : DbContext, IMyDataProvider { public MyDataProvider(SqlConnection existingConnection, bool contextOwnsConnection) : base(existingConnection,contextOwnsConnecti
public class MyDataProvider : DbContext, IMyDataProvider
{
public MyDataProvider(SqlConnection existingConnection, bool contextOwnsConnection)
: base(existingConnection,contextOwnsConnection)
{
((IObjectContextAdapter)this).ObjectContext.CommandTimeout = 60;
Configuration.LazyLoadingEnabled = true;
Configuration.ValidateOnSaveEnabled = true;
Configuration.ProxyCreationEnabled = true;
Configuration.AutoDetectChangesEnabled = true;
}
public new IDbSet<TModel> Set<TModel>() where TModel : class
{
return base.Set<TModel>();
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new EmployeeMapping());
base.OnModelCreating(modelBuilder);
}
public abstract class ServiceBase<TModel> : IDisposable, IService<TModel> where TModel : class, IModel
{
[Dependency]
public IMyDataProvider MyDataProvider { get; set; }
...
}
Global.asax
private static IUnityContainer InitContainer()
{
IUnityContainer unityContainer = new UnityContainer();
Bootstrapper bootstrapper = new Bootstrapper(unityContainer);
return unityContainer;
}
我将UnityContainer的实例传递到Bootstrapper类中。引导程序类自注册所有程序集
在MVC控制器中,我注入了如下业务逻辑:
public class EmployeeController
{
[Dependency("GetEmployees")]
public IBusinessLogic GetEmployees_Operations { get; set; }
public ActionResult EmployeeMain()
{
var employees = GetEmployees_Operations.GetAllEmployees();
...
}
}
在某种程度上,这一切都非常有效。每隔一段时间,我就会从MyDataProvider类中抛出一个异常:“EntityConnection只能用封闭的DbConnection构造”。这似乎发生在MVC站点的高使用率期间。异常非常简单,可以理解,但是我应该如何着手修复它呢
我发现,将实例化业务逻辑类的方式从控制器上的字段更改为ActionResult方法内部,我不会收到异常
例如:
public class EmployeeController
{
//[Dependency("GetEmployees")]
//public IBusinessLogic GetEmployees_Operations { get; set; }
public ActionResult EmployeeMain()
{
IBusinessLogic GetEmployees_Operations = _ioc_Bootstrapper.Resolve(typeof(IBusinessLogic), "GetEmployees") as IBusinessLogic;
var employees = GetEmployees_Operations.GetAllEmployees();
...
}
}
我是否完全错过了这条船,错误地实现了统一
引导程序代码
private void RegisterDAL(String assembly)
{
var currentAssembly = Assembly.LoadFrom(assembly);
var assemblyTypes = currentAssembly.GetTypes();
foreach (var assemblyType in assemblyTypes)
{
...
if (assemblyType.FullName.EndsWith("Provider"))
{
foreach (var requiredInterface in assemblyType.GetInterfaces())
{
if (requiredInterface.FullName.EndsWith("DataProvider"))
{
var typeFrom = assemblyType.GetInterface(requiredInterface.Name);
var typeTo = assemblyType;
var injector = GetInjectorConstructor(assemblyType.Module.Name);
RegisterType(typeFrom, typeTo, false, injector);
}
}
continue;
}
...
}
private InjectionConstructor GetInjectorConstructor(String moduleName)
{
...
connString = String.Concat("Data Source=MySqlServer, ";Initial Catalog=", catalogName, ";Application Name=", applicationName, ";Integrated Security=True; );
var conn = new SqlConnection(connString);
return new InjectionConstructor(conn, true);
}
您的描述缺少(或我找不到)有关如何注册
SqlConnection
的信息。它发生在引导程序中。我在帖子中添加了代码。它不是向提供者的每个新实例注入了相同的连接吗?是的。这对于在事务中包含多个更新是必需的。Sql连接不应同时使用。如果你真的共享同一个连接,它可以解释你在重载下的问题。单个请求下的事务应在单个连接上处理。不同的请求应该使用不同的连接。
public class EmployeeController
{
//[Dependency("GetEmployees")]
//public IBusinessLogic GetEmployees_Operations { get; set; }
public ActionResult EmployeeMain()
{
IBusinessLogic GetEmployees_Operations = _ioc_Bootstrapper.Resolve(typeof(IBusinessLogic), "GetEmployees") as IBusinessLogic;
var employees = GetEmployees_Operations.GetAllEmployees();
...
}
}
private void RegisterDAL(String assembly)
{
var currentAssembly = Assembly.LoadFrom(assembly);
var assemblyTypes = currentAssembly.GetTypes();
foreach (var assemblyType in assemblyTypes)
{
...
if (assemblyType.FullName.EndsWith("Provider"))
{
foreach (var requiredInterface in assemblyType.GetInterfaces())
{
if (requiredInterface.FullName.EndsWith("DataProvider"))
{
var typeFrom = assemblyType.GetInterface(requiredInterface.Name);
var typeTo = assemblyType;
var injector = GetInjectorConstructor(assemblyType.Module.Name);
RegisterType(typeFrom, typeTo, false, injector);
}
}
continue;
}
...
}
private InjectionConstructor GetInjectorConstructor(String moduleName)
{
...
connString = String.Concat("Data Source=MySqlServer, ";Initial Catalog=", catalogName, ";Application Name=", applicationName, ";Integrated Security=True; );
var conn = new SqlConnection(connString);
return new InjectionConstructor(conn, true);
}