簡體   English   中英

實體框架核心:將具有列表的對象添加到DbContext會導致列表為空

[英]Entity Framework Core: Adding an object with a List to a DbContext results in an empty List

我們正在嘗試將實體框架模型保存到數據庫中。

在模型中,軌道始終包含一條消息,並且一條消息的重傳列表中可能包含任意數量的消息。

保存模型時,我們檢查數據庫中是否已存在Track模型; 如果沒有,我們只需將Track添加到DbContext。

public class Track
{
    [Key]
    public Guid TrackId { get; set; }
    public virtual Message Message { get; set; }
}

public class Message
{
    [Key]
    public Guid MessageId { get; set; }
    public Guid TrackId { get; set; }

    public virtual List<Message> Retransmits { get; set; }
}

public void Save (Track track)
{
    using (var context = new DatabaseContext())
    {
        Track foundTrack = Read(track.TrackId); // Returns a Track if it already exists in the database

        if (foundTrack == null)
        {
            context.Add(track);
        }
        else
        {
            // Update the Track. Not relevant to this question
        }

        context.SaveChanges();
    }
}

// Returns a Track if it exists in the database or null
public Track Read(Guid trackId)
{
    using (var context = new DatabaseContext())
    {
        return context.Tracks
            .Include(t => t.Message)
                .ThenInclude(m => m.Retransmits)
                .FirstOrDefault(t => t.TrackId == trackId);
    }
}

將Track添加到DbContext實體框架時,將始終清除“重傳列表”。 這意味着,在調用DbContext.Add之前,消息可以在其重傳列表中包含一個消息,但是在調用DbContext.Add之后,它將突然變為0。實體框架實際上是在清除列表,而不是將其添加到數據庫中。

我們期望重傳列表將添加到DbContext中,並且不會在沒有警告的情況下從模型中刪除。

在調試過程中,我們發現將重發List<Message>List<Message>更改為List<AnyOtherObject>返回預期的結果和數據庫中的行。

似乎因為重傳列表與它所包含的類具有相同的類型(即,一條消息可以包含許多消息),所以實體框架將其區別對待。

我們還嘗試在實體之間配置一對多關系,其中modelBuilder.Entity<Message>().HasMany(m => m.Retransmits)沒有區別。 甚至是modelBuilder.Entity<Message>().HasMany(m => m.Retransmits).WithOne(m => m.Parent) ,其中Parent是對重傳消息的包含對象的引用。 但是,這導致了StackOverflow異常。

實體框架拒絕將列表添加到數據庫的原因可能是什么? 有什么方法可以配置實體框架以允許消息包含重傳列表(消息類型為Message),並按預期將其添加到數據庫中? 還是我們完全在做錯事?

我已在Visual Studio的調試器中附加了行為的圖像。

編輯:我們已經嘗試了最新的穩定的Entity Framework Core 2.2.6版以及Entity Framework Core 3.0.0版-預覽版9。兩個版本中都存在相同的行為。

編輯編輯:以下代碼初始化模型,並應重現該問題。

public void ReproduceIssue ()
{
    // Create a Track and Message
    Track track = new Track()
    {
        Message = new Message()
    };

    track.Message.TrackId = track.TrackId;

    // Create a Retransmitted Message
    Message retransmit = new Message()
    {
        TrackId = track.TrackId
    };

    // Add the Retransmitted Message to the List
    track.Message.Retransmits.Add(retransmit);

    Save(track);
}

我們對模型進行了一些更改。 盡管我相信Entity Framework在發布警告/異常之前絕不應該丟掉任何信息,但我們確實避免了該問題。

我想發布代碼,但是由於最初的問題遺漏了很多代碼細節,所以它有點復雜。 但是,解決方案基本上是使用聯接表在消息之間配置多對多關系。

此后,它的表現符合預期。

暫無
暫無

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

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