实体框架 - 使用“相等”(但不是ReferenceEqual)引用属性插入数据

时间:2018-02-21 15:30:19

标签: c# entity-framework entity-framework-core

我正在使用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

虽然这可以在这么简单的情况下工作,但这在我的实际用例中变得非常复杂,它具有更多的引用属性,它们具有自己的引用属性等等。

有没有更标准/更有效的方法来处理这个问题?

由于

0 个答案:

没有答案