簡體   English   中英

實體框架代碼優先於隱含組合鍵的可選一對多關系

[英]Entity Framework Code First Optional One to Many Relationship on implied Composite Key

更新 :在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; }
}

但是我似乎無法獲得流暢的映射以允許我在審計中插入已填充AffectedId的Action(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);
    }
}

關於如何更改C#而不是SQL的任何建議將不勝感激。

映射不會處理這種情況,但是您可以修改域模型和業務規則來做到這一點。 並且為您的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();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM