![](/img/trans.png)
[英]Unable to map List<> navigational properties using OData, EF Core and AutoMapper
[英]EF Core 3.0 nullable navigational properties
所以 EF Core 预览版 7 发布了,我决定将它与 C# 8 预览版和 .NET Core 3.0 预览版 7 一起使用。假设我有一个表示多对多关系的类:
public class A
{
public int Id { get; set; }
public ICollection<Relation> Relations { get; set; }
}
public class B
{
public int Id { get; set; }
public ICollection<Relation> Relations { get; set; }
}
public class Relation
{
public A A { get; set; }
public B B { get; set; }
public int AId { get; set; }
public int BId { get; set; }
}
我会将它们映射为:
modelBuilder.Entity<A>(entity => entity.HasKey(e => e.Id));
modelBuilder.Entity<B>(entity => entity.HasKey(e => e.Id));
modelBuilder.Entity<Relation>(entity =>
{
entity.HasKey(e => new { e.AId, e.BId });
entity.HasOne(e => e.A).WithMany(a => a.Relations).HasForeignKey(e => e.AId);
entity.HasOne(e => e.B).WithMany(b => b.Relations).HasForeignKey(e => e.BId);
});
现在,因为我可能不想包含关系的一个或两个类,所以A
和B
可以为空。 因此,它们应该可以为空。
var relation = Set<Relations>().Include(r => r.A).First(); // relation.A is not null, but relation.B is null.
所以我将类重写为:
public class Relation
{
public A? A { get; set; }
public B? B { get; set; }
}
但是现在模型构建不起作用,因为这些行:
entity.HasOne(e => e.A).WithMany(a => a.Relations).HasForeignKey(e => e.AId);
entity.HasOne(e => e.B).WithMany(b => b.Relations).HasForeignKey(e => e.BId);
raise CS8602 - Dereference of a possibly null reference
在a.Relations
nad b.Relations
访问中CS8602 - Dereference of a possibly null reference
,我将其设置为解决方案范围内的错误,因为这似乎是一件很明智的事情。
请注意,从另一侧构建模型,因此在A
和B
上配置HasMany
将引发CS8603 - Possible null reference return
。
我能够通过#pragma warning disable CS8602
默默地解决这个问题,但这显然是一种解决方法。 在我看来,它就像 EF Core 中的一种气味,这种用法正确似乎是合理的,并且永远不会引发任何问题null
。 但是,我无法在 EF Core 的 github 上找到这样的问题。
所以问题是,在当前的 EF Core 3.0.0 Preview 7 中,有没有一种方法可以使导航属性为空,而不会在模型构建时发出警告? 如果没有,这确实是一个问题,它是否已知并且我在 EF Core 的 github 上错过了它,还是应该在那里提出它?
正如下面的链接中提到的,您可以使用 null-forgiving 运算符 (!) https://docs.microsoft.com/en-us/ef/core/miscellaneous/nullable-reference-types
所以你的代码必须是:
entity.HasOne(e => e.A!).WithMany(a => a.Relations).HasForeignKey(e => e.AId);
entity.HasOne(e => e.B!).WithMany(b => b.Relations).HasForeignKey(e => e.BId);
我没有使用过.NET Core 3.0预览版7,但这是它在.net Core 2.2上的工作方式,据我所知,对此没有任何更改。 导航属性加载默认情况下设置为显式加载,因此,如果不使用.Include()
属性A和B将为null。 您不必将它们设置为可为空。 通过使用.Include(r => rA)
将加载AId
和BId
将加载属性A,但属性B将为null。
我无法发表评论,所以我将其发布为答案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.