EF Core 3.0可为空的导航属性

时间:2019-07-29 09:40:00

标签: c# .net-core entity-framework-core c#-8.0 entity-framework-core-3.0

因此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);
});

现在,由于我可能不想包含该关系的一个或两个类,因此AB可以为null。因此,它们应该为空。

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);

CS8602 - Dereference of a possibly null referencea.Relations访问权限上提高b.Relations,我认为这是解决方案范围内的错误,因为这样做似乎很明智。

请注意,从另一端进行模型构建,因此在HasManyA上配置B,将会提高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上错过了它,还是应该在那里提出?

1 个答案:

答案 0 :(得分:-1)

我没有使用过.NET Core 3.0预览版7,但这是它在.net Core 2.2上的工作方式,据我所知,对此没有任何更改。导航属性的加载默认设置为显式加载,因此,如果不使用.Include(),则属性A和B将为null。您不必将它们设置为可为空。将使用AId加载BId.Include(r => r.A),将加载属性A,但属性B将为空。

我无法发表评论,所以将其发布为答案。