0

最初にコードのTPTを介してDBにマッピングする継承階層の設定があります。ほとんどの場合、階層は1レベルの深さですが、2レベルの場合もあります。私の基本クラスは次のようになります。

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と呼ばれる他の1つのクラスの親であり、次のようになります。

/// <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のConfigurationクラス(上記のリスト)では、HasKey関数を使用してPageRequestIDが主キーであると言い、EFが慣例と継承によって外部キーAuditEventIDを認識していると想定して、これをマップしようとしています。また、モデルを使用してDBに問題なく書き込むことができることにも注意してください。PageRequestを作成する場合は、PageRequestオブジェクトを作成します。PageRequestとAuditEventの両方の基本クラスで定義されているように、すべての必須フィールドにデータを入力し、コンテキストを介して保存します。EFはAuditEventレコードを作成し、FKを含むpageRequestレコードをAuditEventに戻します。

継承権を使用していないと思うのは、作成したモデルとマッピングを使用して、EFがデータベースを作成できるようにしたことです。PageRequestテーブル(および他のすべての子テーブル)の場合、EFは実際にAuditEventIDと呼ばれる主キーを作成しました(私の構成では別の方法で行うように指示されていますが)。このキーは外部キーとしてもラベル付けされており、主キーとして作成する列(この例ではPageRequestID)は、必須(null不可)として構成されています。したがって、EFがBASEクラスから主キーを取得し、それを子クラスの主キーと外部キーとして使用することは、AuditEventIDの概念が親テーブルと子テーブルに分散しているように見えます。この動作を変更する方法はありますか?

4

1 に答える 1

1

これは機能しなかったと言っていますが、ConfirmationLogオブジェクトを持つテーブルにAuditRequestIDが必要ですか?私はリファレンスを見ています:http://msdn.microsoft.com/en-us/data/jj591617#1.6のデータベースの列にCLRプロパティをマップしないように指定する

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 に答える