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

发布于 2024-12-13 08:32:47 字数 2602 浏览 0 评论 0原文

我有一个用于审核的对象的基类:

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 和 AmendByDbId 链接到 SystemUser 对象:

SystemUser

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

    public string Username
    {
        get;
        set;
    }
}

我有一个类Call 继承自 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'.

我不明白:(

I have a base class for objects that are audited:

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;
    }
}

The CreatedByDbId and AmendedByDbId are linked to a SystemUser object:

SystemUser

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

    public string Username
    {
        get;
        set;
    }
}

I have a class Call that inherits from AuditableObject, which also has other SystemUser properties:

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;}
}

Call database table

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)

I cannot seem to get my mappings right, e.g.

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);

and I always get errors at runtime, such as:

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

I can't figure it out :(

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

草莓酥 2024-12-20 08:32:47

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

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

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

编辑

仔细观察后,我感觉这个模型将非常困难,甚至可能无法绘制地图。

  • 您在类 Call 上有一个导航属性 CreatedBy,但在复杂类型 AuditInfo 上有外键属性 CreatedByDbId基类 AuditableObject 的 code>。我怀疑您是否可以在映射中定义这些属性与 SystemUser 具有相同的关系。

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

  • AuditInfo 是否需要使用复杂类型?不能将其属性直接放入 AuditableObject 中吗:

    公共类 AuditableObject :DomainObject、IAuditable
    {
        ...一些领域
    
        公共 int CreatedByDbId { 获取;放; }
        公共日期时间创建日期{获取;放; }
        公共整数?修正ByDbId { 得到;放; }
        公共日期时间?修正日期 { 得到;放; }
    }
    
  • 如果您这样做,您应该能够从 Call< 中移动 CreatedBy 导航属性/code> 实体到 FK CreatedByDbId 所在的 AuditableObject 基类,然后创建与其他两个导航属性相同的映射,但这次是针对基类类:

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

The last error "Invalid column name 'CreatedBy_SystemUserDbId'" could occur because there is missing a mapping of the CreatedBy navigation property to the CreatedByDbId foreign key column in the database. It should look like this:

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

I don't know the reason for the other three errors at the moment.

Edit

Taking a closer look I have the feeling that this model will be really difficult or perhaps impossible to map.

  • You have a navigation property CreatedBy on the class Call but the foreign key property CreatedByDbId on a complex type AuditInfo of the base class AuditableObject. I have doubt that you can define in the mapping that these properties belong together in the same relationship to SystemUser.

  • Therefore the navigation property CreatedBy should be in AuditInfo where the foreign key CreatedByDbId is. But that's not possible because you cannot put a navigation property into a complex type.

  • Is it necessary to use a complex type for AuditInfo? Can't you put its properties directly into the 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; }
    }
    
  • If you do this you should be able to move the CreatedBy navigation property from the Call entity to the AuditableObject base class where the FK CreatedByDbId lives and then create the same mapping you already did for the other two navigation properties, but this time for the base class:

    modelBuilder.Entity<AuditableObject>()
        .HasRequired(a => a.CreatedBy)
        .WithMany()
        .HasForeignKey(a => a.CreatedById);
    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文