I am using Entity Framework (with a code-first approach) and the database is created successfully with the expected foreign keys and unique key constraints.
I have those two model classes:
public class Foo
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
public Bar Bar { get; set; }
}
public class Bar
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
[Index(IsUnique = true), StringLength(512)]
public string Url { get; set; }
}
And this application code:
var foo = GetData();
using (DatabaseContext db = new DatabaseContext())
{
db.Entry(foo).State = EntityState.Added;
if (foo.Bar != null)
{
var bar = await db.Bar.FirstOrDefaultAsync(x => x.Url == foo.Bar.Url);
if (bar != null)
{
// When I assign an existing entity ...
foo.Bar = bar;
}
}
// ... following exception will be thrown.
await db.SaveChangesAsync();
}
SqlException: Cannot insert duplicate key row in object 'dbo.Bar' with unique index 'IX_Url'. The duplicate key value is (https://api.example.com/rest/v1.0/bar/FD6FAB72-DCE2-47DB-885A-424F3D4A70B6). The statement has been terminated.
I don't understand why Entity Framework is trying to add the navigation property Bar
, even after obtaining and assigning it from the same DbContext
. Similar StackOverflow questions haven't provided any working solution yet.
Please tell me if I need to provide additional information.
Did I forget to set any EF related configuration or something like that? Thank you in advance!
It's because
db.Entry(foo).State = EntityState.Added;
marks the foo.Bar
(and any referenced entity not tracked by the context) as Added
as well.
You should resolve the referenced entities before adding the Foo
entity:
var foo = GetData();
using (DatabaseContext db = new DatabaseContext())
{
// Resolve references
if (foo.Bar != null)
{
var bar = await db.Bar.FirstOrDefaultAsync(x => x.Url == foo.Bar.Url);
if (bar != null)
foo.Bar = bar;
}
// Then add the entity
db.Entry(foo).State = EntityState.Added;
await db.SaveChangesAsync();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With