2

更新: GitHub にサンプル プロジェクトを作成しました。

私の既存のデータベースには、キーのない一般的な監査テーブルがありますが、最初に EF コードを使用してこの監査テーブルに挿入したいと考えています。

既存のレポートは、AffectedId と EntityId に基づいて監査を引き出します。ここで、EntityId は多くの場所でハードコーディングされています。
私はデータベースをリバースエンジニアリングしましたが、これらのテーブル間に明示的な関係はありません...したがって、ここに基本POCOオブジェクトがあります(関係を作成することもできません。既存のシステムです)

public class Audit
{
    public int Id { get; set; }
    public int EntityId { get; set; }
    public string AffectedId { get; set; }       
    public string NewValue { get; set; }
}

public class Action1
{
    public int Id { get; set; }
    public string Desc { get; set; }
}   

public class Action2
{
    public int Id { get; set; }
    public string Desc { get; set; }
}

POCOオブジェクトをこのように見せたいと思います

public class Audit
{
    public int Id { get; set; }
    public int EntityId { get; set; }
    public string AffectedId { get; set; }       
    public string NewValue { get; set; }
    public virtual Action1 Action1 { get; set; } // but I don't want this to change audit table
    public virtual Action2 Action2 { get; set; } // but I don't want this to change audit table
}

public class Action1
{
    public Action1() {this.Audits = new List<Audit>();}
    public int Id { get; set; }
    public string Desc { get; set; }
    public virtual ICollection<Audit> Audits { get; set; }
}   

public class Action2
{
    public Action2() {this.Audits = new List<Audit>();}
    public int Id { get; set; }
    public string Desc { get; set; }
    public virtual ICollection<Audit> Audits { get; set; }
}

しかし、Audit に AffectedId を設定したアクション (1 または 2) を挿入できる流暢なマッピングを取得できないようです。これは私がマッピング オブジェクトについて考えていたことですが、ハードコードされた EntityId キーを正しく機能させることができないようです。

public class AuditMap : EntityTypeConfiguration<Audit>
{
    public AuditMap()
    {
        // Primary Key
        this.HasKey(t => t.Id);


        this.HasOptional(t => t.Action1)
            .WithMany(t => t.Audits)
            .HasForeignKey(t => new {EntityId = 3, AffectedId = t.Id});

        this.HasOptional(t => t.Action2)
            .WithMany(t => t.Audits)
            .HasForeignKey(t => new {EntityId = 5, AffectedId = t.Id});
    }
}

public class Action1 : EntityTypeConfiguration<Action1>
{
    public Action1Map()
    {
        // Primary Key
        this.HasKey(t => t.Id);
    }
}

public class Action2 : EntityTypeConfiguration<Action2>
{
    public Action2Map()
    {
        // Primary Key
        this.HasKey(t => t.Id);
    }
}

SQL ではなく C# を変更する方法についての提案をいただければ幸いです。

4

1 に答える 1

0

マッピングはこのシナリオを処理しませんが、ドメイン モデルとビジネス ルールを変更して処理することができます。また、EntityId の魔法の値の列挙型を使用すると、はるかに優れたものになります。

public class Audit
{
    public int Id { get; set; }
    public int EntityId { get; set; }
    public string AffectedId { get; set; }       
    public string NewValue { get; set; }
}

public abstract class AuditableAction{

    public AuditableAction() {this.Audits = new List<Audit>();}

    public int Id { get; set; }
    public string Desc { get; set; }
    public virtual IList<Audit> Audits { get; set; }

    public void Audit(string description){
        this.Audits.Add(new Audit(){
            EntityId = this.GetEntityId(),
            AffectedId = this.Id,
            NewValue = description
        });
    }

    public abstract int GetEntityId();
}

public class Action1 : AuditableAction
{
    public override int GetEntityId(){
        return AuditCode.Magic3.GetHashCode();
    }
}   

public class Action2 : AuditableAction
{
    public override int GetEntityId(){
        return AuditCode.Magic5.GetHashCode();
    }
}

public enum AuditCode{
    Magic3 = 3,
    Magic5 = 5
}

GitHub コード ダンプに基づく使用法

using (var context = new yunoworkContext())
{
    var a = new Action1() {Id = 4, Desc = Guid.NewGuid().ToString()};

    // This audit should insert an audit with EntityId = 3 and AffectedId = {primary key of the assiciated Action1}
    a.Audit("Console!");
    context.SaveChanges();
}
于 2013-07-25T16:03:12.250 に答える