我有一个非常简单的ASP.NET MVC项目,使用Entity Framework和Entities-> Repositories-> Services-> Controllers->视图分层结构构建。使用依赖注入。
我需要在我的控制器逻辑中做这样的事情(例如简化):
var keyWord = _keywordService.GetByName("blah"); // Service instances are registered by dependency injection
var myFile = new MyFile()
{
FileName = "//FilePath/etc"
};
var myContent = new MediaContent()
{
UploadedFile = myFile
};
myContent.KeyWords.Add(keyword);
_MediaContentService.AddContent(myContent); // Service instances are registered by dependency injection
但我不能。这不起作用,因为显然每次创建对象的新实例(myFile
,MyContent
)时,都会使用它创建一个新的DBContext会话。因此,当我尝试保存myContent
时,从示例中,多个上下文发生冲突,最后我收到了两条错误消息之一:
a)IEntityChangeTracker的多个实例无法引用实体对象。 要么 b)无法定义两个对象之间的关系,因为它们附加到不同的ObjectContext对象。
我明白为什么会这样。每次创建EF实体的新实例时,都会调用DBContext初始化程序并创建新的Context。这可以避免吗? 这是我的自定义DBContext:
public class MyCustomDBContext : IdentityDbContext<ApplicationUser>
{
public MyCustomDBContext (): base("ConnStringName", throwIfV1Schema: false){}
public static MyCustomDBContext Create()
{
return new MyCustomDBContext();
}
public DbSet<FirstEntity> FirstEntity{ get; set; }
//Other entities
.
.
.
}
以下是Startup.Auth最初初始化该调用的方式。这就是应用程序知道如何根据请求创建新上下文的方式:
public void ConfigureAuth(IAppBuilder app)
{
// Configure the db context to use a single instance per request
app.CreatePerOwinContext(MyCustomDBContext.Create);
}
看起来Create()方法不断初始化新的Context实例......我不明白如何在不打破关注点分离的情况下解决它?我不想在应用程序的所有层周围传递DBContext的现有实例。 例如,与This问题一样,提供了在控制器中创建DBContext实例然后将其传递给服务,存储库等的建议。此建议不适用于内置的MVC基础结构。
正如我在第一个示例中尝试的那样,如何创建,处理和链接新对象,然后将它们发送到要保存的服务而不会在多个上下文中丢失?毕竟,每个请求我应该只有一个上下文。
答案 0 :(得分:0)
您应该使用 using
关键字作为解决方案,这将解决您的问题。我在我的项目中使用多个上下文:
using (MyFile myFile = new MyFile())
{
using(MediaContent myContent = new MediaContent())
{
myFile.FileName = "//FilePath/etc";
myContent.UploadedFile = myFile;
myContent.KeyWords.Add(keyword);
_MediaContentService.AddContent(myContent);
}
}
答案 1 :(得分:0)
解决方案是在依赖注入映射文件中为DBContext创建一个映射:
kernel.Bind<MyCustomDBContext>().ToSelf().InRequestScope();