2012-12-28 57 views
0

我有一個繼承層次結構設置,我先通過代碼中的TPT映射到數據庫。在大多數情況下,層次結構是一個層次,但有時它是兩個層次。我的基類看起來是這樣的:EF代碼第一多級繼承問題

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

我的問題是,我是否設置了錯誤的等級? 「孫子」表是否需要它的父母和祖父母的外鍵才能起作用? (如果它確實發現不幸)。

我認爲繼承關係會拋出一些東西,因爲如果我不使用HasRequired()/ WithMany()將PageRequests的子項作爲PageRequests的子項並配置爲PageRequests,那麼事情就可以正常工作。

任何幫助,將不勝感激。

更新

於是,經過進一步調查,我認爲有一個與我試圖使用繼承方式的一個普遍問題。我應該注意到,我試圖將代碼先映射到現有數據庫。在數據庫中,我有我的AuditEvent表和一堆像「PageRequest」這樣的「子」表。頁面請求具有稱爲PageRequestID的自己的主鍵以及名爲AuditEventID的外鍵。其他子表的設置方式相同。在我的PageRequest的配置類(上面列出)中,我試圖通過使用HasKey函數來表示該PageRequestID是主鍵,並假定EF將通過約定和繼承知道外鍵AuditEventID。我還應該注意到,我可以使用該模型寫入數據庫。如果我想寫一個PageRequest,我創建PageRequest對象,填充由PageRequest和AuditEvent基類定義的所有必填字段,並通過上下文進行保存。 EF創建AuditEvent記錄,並將FK的pageRequest記錄返回給AuditEvent。

是什麼讓我覺得我沒有使用繼承權是我允許EF爲我創建我的數據庫,使用我創建的模型和映射。對於PageRequest表(和所有其他子表),EF實際上創建了一個名爲AuditEventID的主鍵(即使我的配置告訴它做其他事情)。該鍵也被標記爲外鍵,並且我想要創建的列作爲主鍵(本示例中爲PageRequestID)僅被配置爲必需(不可爲空)。所以看起來,EF從我的BASE類中獲取主鍵,並將它用作子類中的主鍵和外鍵,就像AuditEventID的概念在父表和子表之間傳播一樣。有沒有辦法改變這種行爲?

+0

我很困惑。我期望列AuditEventID只是因爲它是ConfirmationLogs類的一個屬性。您是否嘗試過使用忽略(a => a.AuditEventID)語句來顯式刪除該字段? – bryanjonker

+0

AuditEventID是基類AuditEvent的屬性,而不是ConfirmationLogs。確認日誌與AuditEvent沒有直接關係,AuditEvent是「祖父母」。 –

+0

忽略()不好意思。 –

回答

1

您是說這不起作用,它仍然期望具有ConfirmationLog對象的表中的AuditRequestID?我期待在參考:指定不映射一個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); 
} 

好運。

+0

不幸的是,沒有奏效。我認爲我遇到的問題是EF期望某個表格佈局使TPT繼承工作,而我沒有這種佈局。 –