多个插入需要设置Id属性?

时间:2014-05-11 10:35:03

标签: c# sql-server entity-framework

将Entity Framework 6.1.0与SQL Server 2008R2结合使用,我无法在单个工作单元中插入多个相同类型的记录(没有黑客攻击),而且我可以'似乎找出了我做错的事情?

我与团体和国家合作,每个国家属于一个集团,集团有一个国家集合。 当我想将3个国家添加到同一组时如下:

using (MyDBContext context = new MyDBContext())
{
    List<Db.Group> groups = context.Groups.ToList();
    Db.Group groupH = groups.First(grp => grp.Name == "H");

    Db.Nation nation1 = new Db.Nation() { Code = "NA1", Name = "Nation 1" };
    //nation1.Id = 1001;
    nation1.Group = groupH;
    nation1.GroupId = groupH.Id;
    nation1.GroupOrdinal = 5;
    context.Nations.Add(nation1);
    Db.Nation nation2 = new Db.Nation() { Code = "NA2", Name = "Nation 2" };
    //nation2.Id = 1002;
    nation2.Group = groupH;
    nation2.GroupId = groupH.Id;
    nation2.GroupOrdinal = 6;
    context.Nations.Add(nation2);
    Db.Nation nation3 = new Db.Nation() { Code = "NA3", Name = "Nation 3" };
    //nation3.Id = 1003;
    nation3.Group = groupH;
    nation3.GroupId = groupH.Id;
    nation3.GroupOrdinal = 7;
    context.Nations.Add(nation3);

    groupH.Nations.Add(nation1);
    groupH.Nations.Add(nation2);
    groupH.Nations.Add(nation3);

    context.SaveChanges();
}

...我收到InvalidOperationException告诉我:The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

但是,当我取消注释为每个新国家分配主键值的3行(即nation1.Id = 1001等)时,插入工作没有问题?

请注意,与数据库中的Nation.Id对应的列是Identity(1,1)列,并且它使用此生成的值插入新的Nation行:它忽略了我的值用代码分配它们 实体框架似乎需要这个值(没有实际使用它),我认为这很奇怪。这不是必要的,对吧?

那么,我做错了什么?

编辑我还创建了一个简单的&#34;参考&#34;只有2个实体尝试隔离问题的项目 - 当然,这个 工作:&#39;) 但是,当我比较ObjectStateManager(即((IObjectContextAdapter)context).ObjectContext.ObjectStateManager)之间的内容时 参考项目和我的真实项目,我注意到它的_entriesWithConceptualNulls成员的内容有所不同:

  • 在我的真实项目中,每个添加的国家都被添加到_entriesWithConceptualNulls集合中,这显然是实体的集合 具有空外键值的地方,他们不允许有外键值(请参阅here)。
  • 在我的参考项目中,当我为每个新国家分配一个Id值时,_entriesWithConceptualNulls仍为空。

更令人惊讶的是,在我的真实项目中,当我只插入一个Nation时,它不需要具有Id值 - _entriesWithConceptualNulls保持为空,并且插入正常工作。 只有当我插入2或3个国家时,才需要Id值......

编辑2 问题 可能位于.edmx我正在使用:当我让Visual Studio从头开始生成新的.edmx时,代码无需设置ID即可正常工作。继续......

2 个答案:

答案 0 :(得分:1)

丢失groupH.Nations.Add(nation1);部分(最后3行)。

你经常做其中的一件事 - 当你设置国家集团(从关系的一方)时,所有这一切 - 再次从集团方面做到这一点似乎加倍(我不记得最近这样做,我希望EF能够处理这个并且不报告重复,但似乎并非如此)。

它基本上是相同关系的一部分,只是它的不同方面,你不需要两者。

答案 1 :(得分:1)

好吧,我明白了。我的项目使用了一个稍微调整过的T4模板,该模板允许每个生成的实体派生自一个公共EntityBase类。此基类还会覆盖Equals()GetHashCode(),在为GetType()返回相同值并且具有相同Id值时,将2个实体定义为相等

显然,对于我的问题中的代码,这会导致3个国家被EF视为相同,从而产生InvalidOperationException。当我明确地为每个新国家分配一个Id时,EF将它们视为3个不同的国家,并且插入按预期执行。

因为我不想要求我的新实体实例拥有Id,所以我更改了Equals(),以便Id为0计为'未初始化':它从不认为ID为0的两个实体为等于。这解决了我。