I have a pretty straightforward ASP.NET MVC project built with Entity Framework and Entities->Repositories->Services->Controllers->Views layered structure. Dependency Injection is utilized.
I need to do something like this in my controller logic (Simplified for the example sake):
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
But I can't. This does not work because apparently every time a new instance of an object is created ( myFile
, MyContent
) - a new session of DBContext gets created with it. So when I try to save myContent
, from the example, multiple Contexts conflict and I end up getting one of the two error messages:
a) An entity object cannot be referenced by multiple instances of IEntityChangeTracker. OR b) The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects.
I understand why this happens though. Every time a new instance of an EF entity is created my DBContext initializer is called and a new Context gets created. Can this be avoided ? Here is my custom 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
.
.
.
}
And here is how that call is initialized at Startup.Auth initially. This is how the application knows where to go to create new Contexts per request:
public void ConfigureAuth(IAppBuilder app)
{
// Configure the db context to use a single instance per request
app.CreatePerOwinContext(MyCustomDBContext.Create);
}
It looks like that Create() method keeps initializing new Context instances... I don't understand how to solve it without breaking the separation of concerns? I don't want to have to pass around an existing instance of DBContext around all layers of the application. Like This question, for example, provided a suggestion to create an instance of DBContext in the controller and then pass it down to services, repositories, etc. This suggestion does not work with built out MVC infrastructure.
As I tried in the first example, how can I create, process and link together new objects, and then send them down to services to be saved without getting lost in multiple Contexts? After all, I should only have one context per request.