实体框架 - 从值对象创建复合PK

时间:2016-09-15 05:20:59

标签: c# sql-server entity-framework-6

如何使用valueobject中的字段在父级中创建复合主键? valueobject在数据库中没有自己的表,我希望将这两个道具插入到父表中。

实体

public class Parent 
{
    public string Name { get;set; }
    public MyValueObject MyValueObj { get;set; }
}

public class MyValueObject
{
    public int Id { get;set; }
    public int SSN { get;set; }
}

父级的DbContext

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Parent>().Property(new { p.MyValueObj.Id, p.MyValueObj.SSN}).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

    base.OnModelCreating(modelBuilder);
} 

我希望Parent表看起来像这样:

Composite PK
-----------
Id      SSN          Name
1       000000       Mikael

1 个答案:

答案 0 :(得分:0)

如果你可以使用继承,那么它应该如下所示:

public class Parent : MyValueObject
{
    public string Name { get;set; }
}

public class MyValueObject
{
    public int Id { get;set; }
    public int SSN { get;set; }
}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Parent>().Property(new { p.Id, p.SSN}).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

    base.OnModelCreating(modelBuilder);
} 

您的实现无法工作的原因非常简单 - 实体框架无法将您的复杂对象(设置为属性)转换为SQL字段,因此它会尝试将其作为其他实现的引用对象表。在我提供的代码中,您没有任何复杂对象作为属性,因此EF将轻松地将所有属性映射到SQL列。

<强>更新 实际上,我做了一些调查,发现article说明你可以使用复杂的类型。我之前从未使用过这个(甚至看过),所以无法向你描述这个问题的所有方面,但我从文章中看到的是这个复杂的属性不能是可选的,所以你需要始终初始化它。我也只能想,但是你可能甚至不需要将那个复杂类型的所有字段标记为主键,所以你应该有这样的东西:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Parent>().Property(p => p.MyValueObj).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

    base.OnModelCreating(modelBuilder);
} 

不确定这是否有效,只需试一试:)