I'm using Entity Framework Core to store an object graph in a database. At various times while I'm building the graph, I create an entity, store it to the database, and the release the context. However, I'm running into an issue where EFC is trying to insert an entity that has already been inserted when it is connected to a new entity. This is best explained with code. Here's a short repro piece of code (this is straight line code, but the two uses of contexts happen at different times and places in the code).
In the second call to context.SaveChanges()
, I get the following exception:
SqlException:
Cannot insert explicit value for identity column in table 'Namespace' when IDENTITY_INSERT is set to OFF.
When I look at the SQL being executed, it is trying to insert the namespace entity again, presumably because myType is being saved to the DB and it has a reference to the dbNamespace
entity.
// see if namespace is in the db and add it if not
string someNamespaceString = "foobar";
CodeDatabase.Models.Namespace dbNamespace;
using (var context = new CodeFactsContext())
{
dbNamespace = context.Namespace.FirstOrDefault(ns => ns.Namespace1 == someNamespaceString);
if (dbNamespace == null)
{
dbNamespace = new Namespace() { Namespace1 = someNamespaceString };
context.Namespace.Add(dbNamespace);
}
context.SaveChanges();
}
// Type entity created somewhere from the code
var myType = new CodeDatabase.Models.Type()
{
FullName = "foobar.mytype",
ShortName = "mytype",
Namespace = dbNamespace // this is already in the DB
};
// check if myType is in the db and add it if not
using (var context = new CodeFactsContext())
{
var dbType = context.Type.FirstOrDefault(t => t.FullName == myType.FullName);
if (dbType == null)
{
dbType = myType;
context.Add(dbType);
}
context.SaveChanges(); // throws exception
}
Any idea how to get EF Core to recognize (in the second context.SaveChanges()
) that myType
should be inserted into the database, but myType.Namespace
should not because it's already there? Both of the entities have an int id that is autogenerated by the DB and the id of Namespace is set to the database value after the first call to SaveChanges
. I thought EF Core would recognize that the id is not 0 and not try to save it. Any help/suggestions very welcomed.