我正在使用EFCore。我有一些包含某些导航属性(技能)的对象(Person)。 我所拥有的Person-objects是以这样的方式创建的,即几个人可能具有相同键的技能,但它们是不同的对象,即具有不同的引用。假设我对这些创建的方式没有影响。
当我尝试通过EFCore插入这些内容时,我面临异常,因为EFCore无法使用相同的键跟踪多个Skill对象:
class Skill : IEquatable<Skill>
{
string Name {get;set;}
bool Equals(Skill other) { ... }
override bool Equals(obj other) { ... }
override int GetHashCode() { ... }
}
class Person
{
string Name {get;set;}
Skill Skill {get;set;}
}
var skill1 = new Skill { Name = "test skill" };
var person1 = new Person { Name = "Person2", Skill = skill1 };
var skill2 = new Skill { Name = "test skill" };
var person2 = new Person { Name = "Person2", Skill = skill2 };
var people = new [] { person1, person2 };
// skill1.Equals(skill2), but this will still throw an exception because EF can't track two skill objects with the same key
Context.People.AddRange(people);
在“原则”中,将此插入数据库应该没有问题 - 技能对象具有相同的密钥,但也是相同的,因此只需要对数据库进行1次INSERT即可。当然,这与EF处理事物的方式以及如何处理变更跟踪不相符。
我能想到的唯一方法是,在创建Person对象之后(请记住,假设我无法控制它), 手动遍历我要插入的所有Person对象,并“统一”所有导航属性。 或者换句话说,将所有相同的Skill对象(Skill.Equals)替换为同一个引用 - 要么是从要添加的对象中取出的,要么是从数据库中检索到的对象,以防它已经包含一个记录。需要key.y
虽然这可以在这么简单的情况下工作,但这在我的实际用例中变得非常复杂,它具有更多的引用属性,它们具有自己的引用属性等等。
有没有更标准/更有效的方法来处理这个问题?
由于