Disconnected entities not recognized as existing
See original GitHub issueI am attempting a simple scenario of adding a disconnected entity, retrieved from one DbContext, to a different entity that is saved within another DbContext.
I have a basic DbContext implementation:
public class EfTestDbContext : DbContext
{
public DbSet<Book> Books { get; set; }
public DbSet<Author> Authors { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseInMemoryDatabase();
}
}
and two simple entities:
public class Author
{
public int ID { get; set; }
public string Name { get; set; }
}
public class Book
{
public int ID { get; set; }
public int AuthorID { get; set; }
public Author Author { get; set; }
public string Name { get; set; }
}
and I am creating and saving the Author
entity within one context, then adding it to the Book
entity within the other context:
static void Main(string[] args)
{
Author existingAuthor;
using (var ctx = new EfTestDbContext())
{
existingAuthor = new Author() { Name = "First author" };
ctx.Add(existingAuthor);
ctx.SaveChanges();
Console.WriteLine($"Saved author ({existingAuthor.Name})");
}
using (var ctx = new EfTestDbContext())
{
var book1 = new Book()
{
Name = "First book",
Author = existingAuthor
};
Console.WriteLine($"Added author ({existingAuthor.Name}) to first book");
Console.WriteLine($"Author is existing: {ctx.Entry(existingAuthor).IsKeySet}");
ctx.Add(book1);
ctx.SaveChanges();
}
}
Although the contexts are separate and the Author entity is disconnected once the first context is disposed, the existingAuthor
entity is recognized as existing, since ctx.Entry(existingAuthor).IsKeySet
returns True
.
I have read the document at https://docs.microsoft.com/en-us/ef/core/saving/disconnected-entities and from what I understand, the IsKeySet
value should be enough to let EF know that the entity already exists in the database and it should not attempt to insert it.
In this example I’m using the In-Memory provider, but I’ve attempted this with SQLite and the result has been the same.
Is this a bug, or am I doing something wrong? Have I understood the document wrong and should I be manually and explicitly tracking which entities have a IsKeySet
value set and which do not?
EF Core version: 2.1.1.
Issue Analytics
- State:
- Created 5 years ago
- Comments:10 (3 by maintainers)
I also performed tests with the latest version of EF (
release/2.2
branch) and the results are the same.I’m out of my depth in examining the true reason, but I tracked it to
NavigationFixer.cs:191
where this existing entity is attached asAdded
when traversing navigation property of the parent (Book
) object. I noticed that change tracker is searching for existing entities in the context in order to determine whether an entity should be added or not (which contradicts with what is written in https://docs.microsoft.com/en-us/ef/core/saving/disconnected-entities or more probably, I’m misreading it):https://docs.microsoft.com/en-us/ef/core/saving/disconnected-entities#with-auto-generated-keys
That lead me to manually attach the disconnected entity using
ctx.Attach(existingAuthor)
and then everything worked – this approach is possible in simple example such as the provided test, but quite hard to achieve with repository implementations in different contexts.So the puzzle remains - is there something special we need to tell EF that it should detected the entities correctly as modified?
@ajcvickers, I have observed what you write in practice, so it makes perfect sense. The reason Patrik opened this ticket is because we were actually investigating why this does not work according to the docs. I suppose we could agree that the docs are a little misleading. Take this paragraph for example (emphasis mine):
Anyhow, now that we know what is going on behind the scenes, we’re all set. I was afraid we were doing something wrong or stumbling on a bug, but it has obviously been designed that way.
I appreciate your time responding to this issue. Thanks!