我有以下结构:
public class Message
{
...
public MessageType MessageType { get; set; }
public ICollection<Product> Products { get; set; }
public ICollection<Product> ProductsWhereThisIsDefaultCompletedSale { get; set; }
}
public class Product
{
...
public Guid? DefaultCompletedSaleMessageId { get; set; }
public Message DefaultCompletedSaleMessage { get; set; }
public ICollection<Message> Messages { get; set; }
}
public MessageType {...}
和映射器:
EntityTypeBuilder<Product> entityBuilder;
entityBuilder
.HasMany(p => p.Messages)
.WithMany(m => m.Products);
entityBuilder
.HasOne(p => p.DefaultCompletedSaleMessage)
.WithMany(m => m.ProductsWhereThisIsDefaultCompletedSale)
.OnDelete(Microsoft.EntityFrameworkCore.DeleteBehavior.NoAction);
这与数据库配合得很好(至少我这么认为......)。当我将新产品添加到 Messages
集合中时,它会添加到 ProductsMessages
关系表中。当我急于加载记录时,它们就会被加载(Include(...))。
问题是,我试图让所有导航属性在某些特定场景下自动包含它们。但这不能正常工作。当我在 Message 上运行 entityType.GetNavigations()
( doc ) 时,它不会返回 Products
,它只返回其他两个导航属性 ProductsWhereThisIsDefaultCompletedSale
和 MessageType
:
关于我做错了什么有什么想法吗?
如果您需要更多信息,请告诉我。我使用的是.NET5。谢谢!
最佳答案
这是因为这些是所谓的跳过导航,在 EF Core 5.0 中引入,用于通过隐式联接实体实现多对多。
他们由 ISkipNavigation 代表接口(interface),对于某些设计决策不继承 INavigation由 GetNavigations
方法返回的接口(interface),因此可以使用名为 GetSkipNavigations
的单独方法来检索它们。 .
但是 INavigation
和 ISkipNavigation
共享一个通用接口(interface) INavigationBase
,因此,如果它的属性/方法足以满足您尝试使用它们执行的操作,您可以使用类似以下内容获得两种类型的集合导航(需要 using Microsoft.EntityFrameworkCore.Metadata;
):
var allNavigations = entityType.GetNavigations()
.Concat<INavigationBase>(entityType.GetSkipNavigations());
关于c# - EF Core GetNavigations 忽略集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67546883/