1

我想我在这里遗漏了一些简单的东西。我收到错误消息:

“违反 PRIMARY KEY 约束 'PK_FeatureTypes'。无法在对象 'dbo.FeatureTypeCodes' 中插入重复键。重复键值为 (28)。\r\n语句已终止”

我有一个 FeatureType - (Mountain, Lake, River, etc.) 的查找/链接表,它已经填充了数据并定义为:

[Table("FeatureTypeCodes")]
public class FeatureTypeCode {
    [DatabaseGenerated(DatabaseGeneratedOption.None)] 
    public int FeatureTypeCodeID { get; set; }
    public string Name { get; set; }
}

这链接到我的位置表/对象,如下所示:

[Table("Places")]
public class Place {
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int PlaceID { get; set; }
    public string Name { get; set; }
    public FeatureTypeCode FeatureTypeCode { get; set; }
    public ICollection<PlaceCoordinate> PlaceCoordinates { get; set; }
}

然后我像这样从旧数据库中加载它们(它是我的转换代码的一部分):

foreach (DataRow r in table.Rows) {
        int ftID = Convert.ToInt32(r["FeatureTypeId"]);
        Place temp = new Place {
                PlaceID = Convert.ToInt32(r["PlaceID"]),
                Name = r["PlaceName"].ToString(),
                FeatureTypeCode = featureTypeCodeRepository.FeatureTypeCodes.FirstOrDefault(o=>o.FeatureTypeCodeID == ftID)
            };
            places.Add(temp);
        }

当它在保存地点时尝试插入具有与现有对象相同 ID 的新 FeatureType 对象时,会生成错误。我的想法是,通过从上下文中加载 FeatureType,它不会尝试在保存 Place 对象时插入新的 FeatureType。我显然错了,但我错过了一些简单的事情吗?

4

2 回答 2

2

我不认为你在你的featureTypeCodeRepositoryplaces.Add(temp);. 所以我认为基本上 EF 不会跟踪 FeatureTypeCodes,因为它是由一个上下文加载并由另一个上下文保存的。

于 2012-12-11T22:09:36.703 回答
0

虽然我认为 Simon Edström 是正确的 (+1),但您也可以考虑在您的课程中公开原始外键字段(类似于FeatureTypeId?)Place。然后你可以简单地设置

FeatureTypeId = ftID;

如果您不确定 FK 字段值是否真的存在于表中,您可以使用即使它具有不同的上下文FeatureTypeCodes来查询它的存在。featureTypeCodeRepository使用Any()是最便宜的方法:

var exists = featureTypeCodeRepository.FeatureTypeCodes
                 .Any(o => o.FeatureTypeCodeID == ftID)

在实体框架中这样做并不少见。仅由引用(like Place.FeatureTypeCode)组成的关系称为独立关联,即具有引用和原始 FK 属性外键关联的关联。Julia Lerman 在她的书DbContext 中

除非您有充分的理由不公开外键属性,否则通过包含它们将为您省去很多痛苦

于 2012-12-12T00:12:22.260 回答