2011-11-03 118 views
2

我有对象的基类所审核:EF代码优先映射复杂类型关系

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'. 

我无法弄清楚:(

回答

0

最后的错误“无效的列名称CreatedBy_SystemUserDbId'”可能会出现,因为缺少数据库中CreatedBy导航属性到CreatedByDbId外键列的映射。它应该如下所示:

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

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

编辑

更仔细地看我有一种感觉,这种模式将是非常困难或者是不可能的映射。

  • 您对该类Call但在基类AuditableObject的复合型AuditInfo外键属性CreatedByDbId导航属性CreatedBy。我怀疑你可以在映射中定义这些属性与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导航属性从Call实体移动到AuditableObject基类,其中FK CreatedByDbId生活,然后创建你已经做了其他两个导航属性相同的映射,但此时基类:

    modelBuilder.Entity<AuditableObject>() 
        .HasRequired(a => a.CreatedBy) 
        .WithMany() 
        .HasForeignKey(a => a.CreatedById);