EF代码优先映射复杂类型关系

时间:2011-11-03 11:02:24

标签: entity-framework entity-framework-4.1 ef-code-first

我有一个被审计对象的基类:

AuditableObject

public class AuditableObject : DomainObject, IAuditable
{
    ... some fields

   public AuditInfo AuditInfo
   {
        get;
        set;
   }
}

AuditInfo

public class AuditInfo : IAuditable
{

    public int CreatedByDbId
    {
        get;
        set;
    }

    public DateTime CreatedDate
    {
        get;
        set;
    }

    public int? AmendedByDbId
    {
        get;
        set;
    }

    public DateTime? AmendedDate
    {
        get;
        set;
    }
}

CreatedByDbId和AmendedByDbId链接到SystemUser对象:

SystemUser

public class SystemUser
{
    public int SystemUserDbId
    {
        get;
        set;
    }

    public string Username
    {
        get;
        set;
    }
}

我有一个继承自AuditableObject的类调用,它还具有其他SystemUser属性:

public class Call : AuditableObject
{
    ... some fields

    public SystemUser TakenBy { get; set;}
    public SystemUser CreatedBy { get; set; }
    public SystemUser CancelledBy { get; set;}
    public int CancelledByDbId {get; set;}
    public int TakenByDbId { get; set;}
}

调用数据库表

CREATE TABLE [dbo].[Call](
[CallDbId] [int] IDENTITY(1,1) NOT NULL,
[CancelledBy] [int] NULL,
[CreatedByDbId] [int] NOT NULL,
[CreatedDate] [datetime] NOT NULL,
[AmendedByDbId] [int] NULL,
[AmendedDate] [datetime] NULL,
[TakenBy] [int] NOT NULL)

我似乎无法使我的映射正确,例如。

modelBuilder.ComplexType<AuditInfo>();
...// configuration for Call
this.Property(x => x.AuditInfo.AmendedByDbId).HasColumnName("AmendedByDbId");
this.Property(x => x.AuditInfo.AmendedDate).HasColumnName("AmendedDate");
this.Property(x => x.AuditInfo.CreatedByDbId).HasColumnName("CreatedByDbId");
this.Property(x => x.AuditInfo.CreatedDate).HasColumnName("CreatedDate");

this.Property(t => t.CancelledByDbId).HasColumnName("CancelledBy");
this.Property(t => t.TakenByDbId).HasColumnName("TakenBy");

this.HasRequired(t => t.TakenBy).WithMany().HasForeignKey(x => x.TakenByDbId);
this.HasRequired(t => t.CancelledBy).WithMany().HasForeignKey(x => x.CancelledByDbId);

我总是在运行时遇到错误,例如:

Invalid column name 'SystemUser_SystemUserDbId'.
Invalid column name 'SystemUser_SystemUserDbId1'.
Invalid column name 'SystemUser_SystemUserDbId2'.
Invalid column name 'CreatedBy_SystemUserDbId'.

我无法弄明白:(

1 个答案:

答案 0 :(得分:0)

上一个错误“无效的列名称'CreatedBy_SystemUserDbId'”可能会发生,因为缺少CreatedBy导航属性到CreatedByDbId外键列的映射数据库。它应该是这样的:

this.HasRequired(t => t.CreatedBy)
    .WithMany()
    .Map(c => c.MapKey("CreatedByDbId"));

目前我不知道其他三个错误的原因。

修改

仔细观察我觉得这个模型真的很难或者可能无法映射。

  • 您在类CreatedBy上有一个导航属性Call,但在基类{{1}的复杂类型CreatedByDbId上有外键属性AuditInfo }}。我怀疑你可以在映射中定义这些属性与AuditableObject处于同一关系中。

  • 因此,导航属性SystemUser应位于外键CreatedBy所在的AuditInfo中。但这是不可能的,因为你不能将导航属性放入复杂类型。

  • 是否有必要为CreatedByDbId使用复杂类型?您不能将其属性直接放入AuditInfo

    AuditableObject
  • 如果您这样做,您应该能够将public class AuditableObject : DomainObject, IAuditable { ... some fields public int CreatedByDbId { get; set; } public DateTime CreatedDate { get; set; } public int? AmendedByDbId { get; set; } public DateTime? AmendedDate { get; set; } } 导航属性从CreatedBy实体移动到FK Call生活的AuditableObject基类然后为其他两个导航属性创建相同的映射,但这次是基类:

    CreatedByDbId