簡體   English   中英

保存具有多個父項的EF實例

[英]Saving an EF instance which has multiple parents

從業務邏輯對象映射回EF對象時,我遇到的主要問題之一是同一個實例有2個父對象的情況:

在此輸入圖像描述

(對象為黃色,屬性為橙色)

在業務邏輯世界中,這里只有一個Tree對象的實例(它顯示為多個父項的子項:Forest和Section)

當我使用AutoMapper將所有內容映射回EF對象時,EF認為有兩個獨立的樹實例(盡管它們具有相同的ID)。 因此,它在DB中創建副本。

管理此方案的正確方法是什么,以便Forest和Section指向DB中相同的Tree記錄?

我們是否必須通過手動確保所有附件都被認為是重復的?

不幸的是,EF需要獲取Tree對象的相同實例,以便在保存整個Forest圖形時將其視為相同(覆蓋其平等成員沒有幫助),這不是Automapper默認情況下映射對象圖形的方式。

但您可以按照映射期間重用現有實例的方式設置Automapper配置:

var config = new MapperConfiguration(cfg =>
{
   cfg.CreateMap<Tree, TreeEF>().PreserveReferences();
});

如果你的bussines模型中的ForestSection有一個對Tree的同一個實例的子引用,那么這個引用將被保留,並且不會創建重復項。

編輯

class Program
{
    static void Main(string[] args)
    {
        var config = new MapperConfiguration(cfg =>
            {
                cfg.CreateMap<Forest, ForestEF>().PreserveReferences();
                cfg.CreateMap<Section, SectionEF>().PreserveReferences();
                cfg.CreateMap<Tree, TreeEF>().PreserveReferences();
            });

        var mapper = config.CreateMapper();

        var forest = new Forest();
        var section = new Section();
        var tree = new Tree();

        forest.Trees.Add(tree);
        forest.Sections.Add(section);
        section.Trees.Add(tree);

        var result = mapper.Map<Forest, ForestEF>(forest);

        Console.WriteLine(object.ReferenceEquals(result.Trees[0], result.Sections[0].Trees[0]));
        Console.ReadLine();
    }
}

public class Forest
{
    public IList<Tree> Trees { get; set; } = new List<Tree>();
    public IList<Section> Sections { get; set; } = new List<Section>();
}

public class Section
{
    public IList<Tree> Trees { get; set; } = new List<Tree>();
}

public class Tree
{
}

public class ForestEF
{
    public IList<TreeEF> Trees { get; set; } = new List<TreeEF>();
    public IList<SectionEF> Sections { get; set; } = new List<SectionEF>();
}

public class SectionEF
{
    public IList<TreeEF> Trees { get; set; } = new List<TreeEF>();
}

public class TreeEF
{
}

我相信如果你不想在這里重復,那么兩個孩子不僅必須引用ID而且還要引用內存中的特定實例,因此EF知道它應該是相同的記錄(導航屬性)。 否則,您必須先保存父記錄,然后在事后將密鑰分配給每個子記錄。 如果這不是GUID而是自動生成的id,那么您可能需要使用相同的引用。

暫無
暫無

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

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