![](/img/trans.png)
[英]Get List of Entity Models in DbContext Entity Framework Core 2.1
[英]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.