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 认为列 AuditEventID(基类的主键)存在于 ConfirmationLogs 表(孙表)上。ConfirmationLogs 表具有其父表 (PageRequests) 的外键,然后该表具有其父表 (AuditEvents) 的外键。

我的问题是,我把这个层次结构设置错了吗?“孙子”表是否需要它的父母和祖父母的外键才能起作用?(如果确实如此,我觉得很不幸)。

我很肯定继承关系正在把事情搞砸,因为如果我不让 ConfirmationLogs 成为 PageRequests 的子节点并使用 HasRequired()/WithMany() 配置与 PageRequests 的关系,那么一切正常。

任何帮助,将不胜感激。

更新

因此,经过进一步调查,我认为我尝试使用继承的方式存在普遍问题。我应该注意,我正在尝试首先将代码映射到现有数据库。在数据库中,我有我的 AuditEvent 表和一堆“子”表,如 PageRequest。页面请求有它自己的称为 PageRequestID 的主键,以及一个称为 AuditEventID 的外键。其他子表的设置方式相同。在我的 PageRequest 配置类(上面列出)中,我试图通过使用 HasKey 函数来映射它,说 PageRequestID 是主键,并假设 EF 将通过约定和继承知道外键 AuditEventID。我还应该注意,我可以很好地使用模型写入数据库。如果我想写一个 PageRequest,我创建 PageRequest 对象,填充 PageRequest 和 AuditEvent 基类定义的所有必需字段,并通过上下文保存。EF 创建 AuditEvent 记录,并将 pageRequest 记录与 FK 返回到 AuditEvent。

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

4

1 回答 1

1

您是说这不起作用,并且它仍然期望具有 ConfirmationLog 对象的表中有一个 AuditRequestID?我正在查看参考资料:Specifying Not to Map a CLR Property to a Column in the Database in 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);
}

祝你好运。

于 2012-12-28T20:06:31.903 回答