2011-05-10 74 views
1

使用EF 4.0和POCO的4.1升级/代码优先。如何在不使用HasForeignKey的情况下引用外键()

好吧,所以我有一个域模型,其中Car类型在一个集合中有Part类型的多个对象。所以一个:很多关系。

HasMany(v => v.Parts) 
    .WithRequired() 
    .HasForeignKey(v => v.CarId) 
    .WillCascadeOnDelete(); 

这里的问题是,它需要我去CarId属性添加到我的Part类型。这是将ORM细节泄漏到我的域模型中 - 这很糟糕。标记虚拟内容已经够烦人的了。

看着为HasForeignKey()方法的XML文档注释这样说:

配置使用的是 对象模型暴露 外键属性(一个或多个)的关系。 如果 外键属性不是 暴露在对象模型中,则使用 的Map方法。

这是伟大的,所有。但它引入了一个catch-22的情况,因为如果我通过删除CarId属性来重构我的Part类型,我不想要并更新我的EF模型构建器以便不打扰映射该属性。然后,你可以想像这意味着我不能再调用HasKey()定义组合键,鼻翼:

HasKey(v => new { v.CarId, v.PartId }); 

HasKey()似乎并不支持定义一种基于非财产lambda表达式的关键。

这里有什么解决方案?

+0

我认为你的问题标题应该是:“如何定义一个主键,而不必将所有主键列暴露为模型中的属性?”这不是问题吗?通过杀死“CarId”,你不仅要移除FK属性(这很容易),而且也是你复杂PK的一部分(这可能是不可能的)。 – Slauma 2011-05-10 15:06:55

+0

你是对的。这里的关键是我不想在我的领域模型中使用多余的“后向引用”。领域模型不需要他们,他们只是一个痛苦,保持同步。我很惊讶EF似乎需要用反向引用来污染我的领域模型 - 这纯粹是一个RDBMS问题。 – nbevans 2011-05-12 11:45:05

+0

您不需要在EF中返回引用,它是可选的。你的问题是你有一个复合主键,并且它的一部分是一个外键。通常情况下,你可以摆脱外键属性,但不是在你的情况下,因为它是同时PK的一部分。而且你不能从模型类中删除PK。你最好的选择是将'PartId'作为主键,然后你可以删除'CarId'。这基本上是hazimdikenli在他的回答中提出的。 – Slauma 2011-05-12 12:44:34

回答

1

如果您绝对不希望在模型中使用外键属性,则可以移除约定以检测FK属性,以避免EF自动将属性标记为FK属性...

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Conventions 
     .Remove<NavigationPropertyNameForeignKeyDiscoveryConvention>(); 
} 

...然后干脆不指定在映射的FK属性:在你的模型

HasMany(v => v.Parts) 
    .WithRequired() 
    .WillCascadeOnDelete(); 

你仍然需要CarId,因为它是主要的一部分关键,但这样它就不会起作用作为外国关键财产。

只是一个想法,我不知道它是否工作。

1

那么,怎么样像CarPartId添加一个新的关键字到CarParts表,所以你不需要组合键。 (使用ORM时复合键支持并不是那么好)

相关问题