实体框架6定义了一个REALLY可选外键

时间:2015-01-21 19:56:05

标签: sql-server tsql ef-code-first entity-framework-6 foreign-key-relationship

说我有两张桌子:

Products
[ProductID] PK
[Weight]
[ProductCode]

KnownProductCodes
[ProductCode] PK
[Description]

现在我希望我的Product实体拥有KnownProductCodeDetails属性。但有趣的是,Products.ProductCode可能包含KnownProductCodes表中存在的EITHER产品代码,或KnownProductCodes表中不存在的产品代码。

所以,我的问题是:如何在Entity Framework中的两个实体之间创建这样的关系?

PS。顺便说一下,实体是否有可能在没有数据库中相应约束的情况下拥有外来关系?

谢谢!

== 详情:EF 6.1.2,Code first

1 个答案:

答案 0 :(得分:1)

这种关联不会是外键。

FK是约束,它使用实体的主键值来限制引用实体中的值域。但是,您不希望约束值Product.ProductCode,因此根据定义,此字段不能是外键。 (从技术上讲)。

第二点是有意义的主键,如KnownProductCodes.ProductCode,几乎总是一个坏主意,因为有一天企业可能会要求改变它们的价值观。更改主键值很麻烦。

所以这里显而易见的事情是为新的主键字段KnownProductCodesId创建一个真正可为空的外键。然后,您可以从此FK(如果不为空)或Product.ProductCode获取产品的产品代码的显示值。现在很容易修改KnownProductCodes.ProductCode

另一种方法可能是创建“自由联想”。让这成为你的课程:

public class Product
{
    public int ProductID { get; set; }
    public decimal? Weight { get; set; }
    public string ProductCode { get; set; }
    public virtual KnownProductCode KnownProductCode { get; set; }
}

public partial class KnownProductCode
{
    public string ProductCode { get; set; }
    public string Description { get; set; }
}

现在,在映射中,您可以定义它们之间的关联:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<KnownProductCode>().HasKey(k => k.ProductCode);
    modelBuilder.Entity<Product>()
        .HasOptional(p => p.KnownProductCode)
        .WithMany()
        .HasForeignKey(p => p.ProductCode);
}

但是在数据库中你避免创建实际的FK。 EF将允许,它只希望关联指向实体的主键,但关联不必是数据库中的硬FK。

(但请注意,如果您从模型创建数据库,则会采取特殊措施,我不建议这样做。)