首页 文章

EF Code First多级继承问题

提问于
浏览
0

我有一个继承层次结构设置,我首先通过代码中的TPT映射到数据库 . 在大多数情况下,层次结构是一层深,但有时它是两层 . 我的基类看起来像这样:

public class AuditEvent
{
    public int AuditEventID;

    //other stuff
};

然后我有一堆看起来像这样的其他类(具有不同的名称和属性):

public class PageRequest : AuditEvent
{
    /// <summary>
    /// Page Request Id (Primary Key)
    /// </summary>        
    public Int64 PageRequestID { get; set; }

    /// <summary>
    /// Screen (page) being requested
    /// </summary>        
    public string Screen { get; set; }

    /// <summary>
    /// Http Method
    /// </summary>        
    public string HttpMethod { get; set; }

    /// <summary>
    /// Confirmation Logs linked to this page request
    /// </summary>
    public virtual List<ConfirmationLog> ConfirmationLogs { get; set; }
}

这个特定的类(PageRequest)是另一个名为ConfirmationLog的类的父类,如下所示:

/// <summary>
/// Object used to log confirmations to the auditing database
/// </summary>
public class ConfirmationLog : PageRequest
{
    /// <summary>
    /// Confirmation ID
    /// </summary>        
    public long ConfirmationID { get; set; }

    /// <summary>
    /// Confirmation number
    /// </summary>
    public string ConfirmationNum { get; set; }

    /// <summary>
    /// Web action ID (automated alert or transaciton confirmation number)
    /// </summary>
    public int WebActionID { get; set; }
}

我正在使用配置类和流畅的API配置映射,如下所示:

/// <summary>
/// Configuration class for PageRequest
/// </summary>
public class PageRequestConfiguration : EntityTypeConfiguration<PageRequest>
{
    /// <summary>
    /// Default constructor
    /// </summary>
    public PageRequestConfiguration()
    {
        //Table
        ToTable("PageRequests");

        //primary key
        HasKey(a => a.PageRequestID);

        //Properties
        Property(a => a.PageRequestID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        Property(a => a.Screen).IsRequired().HasMaxLength(100);
        Property(a => a.HttpMethod).IsRequired().HasMaxLength(10);
    }
}

/// <summary>
/// Confirmation Log configuration class.  Configures the confirmation log class for the db model
/// </summary>
public class ConfirmationLogConfiguration : EntityTypeConfiguration<ConfirmationLog>
{
    /// <summary>
    /// Default constructor
    /// </summary>
    public ConfirmationLogConfiguration()
    {
        //Map to Table
        ToTable("ConfirmationLogs");

        //Primary Key
        HasKey(a => a.ConfirmationID);

        //required fields
        Property(a => a.ConfirmationID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        Property(a => a.PageRequestID).IsRequired();
        Property(a => a.ConfirmationNum).IsRequired().HasMaxLength(12);
        Property(a => a.WebActionID).IsRequired();
    }
}

然后,我基于此层次结构创建了一个相当大的LINQ查询 . 我会保留那个查询,因为它是由大约10个步骤组成的,我不认为这是我的问题的根源 . 问题是,当我运行查询时,由于某种原因生成的SQL认为在ConfirmationLogs表(孙表)上存在AuditEventID列(基类的主键) . ConfirmationLogs表具有其父表(PageRequests)的外键,该表具有其父表(AuditEvents)的外键 .

我的问题是,我是否错误地设置了这种层次结构? “孙子”表是否需要外键才能使用它的父级和祖父级才能运行? (如果是的话,我觉得不幸) .

我很肯定继承关系正在抛弃,因为如果我不让ConfirmationLogs成为PageRequests的子节点并使用HasRequired()/ WithMany()配置与PageRequests的关系,那么事情就可以了 .

任何帮助,将不胜感激 .

Update

因此,经过进一步调查后,我认为我试图使用继承的方式存在一般性问题 . 我应该注意到我正在尝试将代码首先映射到现有数据库 . 在数据库中,我有我的AuditEvent表和一堆像PageRequest这样的“子”表 . 页面请求具有名为PageRequestID的主键,以及名为AuditEventID的外键 . 其他子表的设置方式相同 . 在我的PageRequest的Configuration类(上面列出的)中,我试图通过使用HasKey函数来表示PageRequestID是主键,并假设EF将通过约定和继承了解外键AuditEventID . 我还应该注意,我可以使用模型写入数据库 . 如果我想编写PageRequest,我创建PageRequest对象,填充PageRequest和AuditEvent基类定义的所有必需字段,并通过上下文保存 . EF创建AuditEvent记录,并将带有FK的pageRequest记录返回到AuditEvent .

让我觉得我没有正确使用继承的原因是我允许EF使用我创建的模型和映射为我创建数据库 . 对于PageRequest表(以及所有其他子表),EF实际上创建了一个名为AuditEventID的主键(即使我的配置告诉它不这样做) . 此键也标记为外键,我想要创建为主键的列(本例中为PageRequestID)只是配置为必需(不可为空) . 因此看起来EF从我的BASE类中获取主键并将其用作我的子类中的主键和外键,几乎就像AuditEventID的概念在父表和子表之间传播 . 有没有办法改变这种行为?

1 回答

  • 1

    你说这个没有't work, and it still expected an AuditRequestID in the table that had the ConfirmationLog object? I'正在查看引用:指定不将CLR属性映射到数据库中的列http://msdn.microsoft.com/en-us/data/jj591617#1.6

    public ConfirmationLogConfiguration()
    {
        //Map to Table
        ToTable("ConfirmationLogs");
    
        //Primary Key
        HasKey(a => a.ConfirmationID);
    
        //required fields
        Property(a => a.ConfirmationID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        Property(a => a.PageRequestID).IsRequired();
        Property(a => a.ConfirmationNum).IsRequired().HasMaxLength(12);
        Property(a => a.WebActionID).IsRequired();
    
        Ignore(a => a.AuditEventID);
    }
    

    祝好运 .

相关问题