Предполагается, что модель будет выглядеть следующим образом:
class Foo {
virtual Bar Bar {get; set ;}
}
class Bar {
int Id { get; set; }
string Property {get; set;}
}
class MyContext {
virtual DbSet<Foo> Foos {get; set;}
void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Bar>()
.HasKey(c => c.Property);
}
}
И некоторый код, подобный:
void DoStuff() {
var foos = GetFoosFromExternalSource();
using(var ctx = new MyContext() {
foreach(var foo in foos) {
ctx.Foos.Add(foo);
}
ctx.SaveChanges();
}
}
IEnumerable<Foo> GetFoosFromExternalSource() {
yield return new Foo {
Bar = new Bar { Id = 1, Property = "Hello" }
};
yield return new Foo {
Bar = new Bar { Id = 2, Property = "World" }
};
yield return new Foo {
Bar = new Bar { Id = 1, Property = "Hello" }
}
}
Это исключение:
Нарушение PRIMARY KEYограничение 'PK_dbo.Bar'.Невозможно вставить дубликат ключа в объект 'dbo.Bar'.Значение дубликата ключа (Hello).
Как я могу объяснить EF, что если объект Bar имеет тот же ключ (или Id, или оба), что он считается одним и тем же экземпляром?
Я знаю, что если бы я мог сделать что-то вроде
IEnumerable<Foo> GetFoosFromExternalSource() {
var bar1 = new Bar { Id = 1, Property = "Hello" };
var bar2 = new Bar { Id = 2, Property = "World" };
yield return new Foo {
Bar = bar1
};
yield return new Foo {
Bar = bar2
};
yield return new Foo {
Bar = bar1
}
}
Это бы хорошо работало.Однако, поскольку это данные, поступающие из внешнего источника, это невозможно сделать напрямую.Мой реальный сценарий имеет несколько уровней и много свойств.Поэтому я хотел бы решить это в модели.