使用 EF Core 2.1 继承进行过滤

Mar*_*koo 4 c# entity-framework-core .net-core ef-core-2.1

当使用继承的对象时,我试图找到一种方法来过滤 EF Core 2.1 中的结果。

我有一个基本模型和几个继承的类(但我只包含了一个):

public class Like {
    public int Id { get; set; }
    public LikeType LikeType { get; set; }
}

public class DocumentLike : Like {
    [ForeignKey(nameof(Document))]
    public int DocumentId { get; set; }
    public virtual Document Document { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

LikeType是一个枚举,它被定义为 dbcontext 中的鉴别器。每个Document都有一个布尔属性.IsCurrent。

要从数据库中获取所有项目,我正在使用如下查询:

IQueryable<Like> query = _context.Set<Like>()
    .Include(x => x.Owner)
    .Include(x => (x as DocumentLike).Document.DocumentType)
    .Include(x => (x as ProductLike).Product)
    .Include(x => (x as TrainingLike).Training)
Run Code Online (Sandbox Code Playgroud)

这工作得很好,并返回包含子对象的所有对象,没有任何错误。我想要做的是从数据库中获取链接文档具有的所有项目.IsCurrent == true。我尝试将以下内容添加到上面的查询中,但都导致异常:

.Where(x => (x as DocumentLike).Document.IsCurrent == true)
Run Code Online (Sandbox Code Playgroud)

和:

.Where(x => x.LikeType == LikeType.Document ? (x as DocumentLike).Document.IsCurrent == true : true) 
Run Code Online (Sandbox Code Playgroud)

执行查询时抛出的异常:

NullReferenceException: Object reference not set to an instance of an object.
    lambda_method(Closure , TransparentIdentifier<TransparentIdentifier<TransparentIdentifier<TransparentIdentifier<TransparentIdentifier<TransparentIdentifier<TransparentIdentifier<TransparentIdentifier<TransparentIdentifier<TransparentIdentifier<TransparentIdentifier<TransparentIdentifier<Like, ApplicationUser>, Organisation>, Training>, Product>, Platform>, NewsItem>, Event>, Document>, DocumentType>, Course>, CourseType>, ApplicationUser> )
    System.Linq.Utilities+<>c__DisplayClass1_0<TSource>.<CombinePredicates>b__0(TSource x)
    System.Linq.Enumerable+WhereSelectEnumerableIterator<TSource, TResult>.MoveNext()
    Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider._TrackEntities<TOut, TIn>(IEnumerable<TOut> results, QueryContext queryContext, IList<EntityTrackingInfo> entityTrackingInfos, IList<Func<TIn, object>> entityAccessors)+MoveNext()
    Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider+ExceptionInterceptor<T>+EnumeratorExceptionInterceptor.MoveNext()
    System.Collections.Generic.List<T>.AddEnumerable(IEnumerable<T> enumerable)
    System.Linq.Enumerable.ToList<TSource>(IEnumerable<TSource> source)
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点?

更新: 澄清:我希望获得一个Like从数据库中返回所有对象的查询,而不管它们的(子)类型如何。如果子类型是DocumentLike,我只想要链接到具有.IsCurrent == true.

Mar*_*koo 6

诀窍是稍微编辑谓词,如下所示:

.Where(x => !(x is DocumentLike) || ((DocumentLike)x).Document.IsCurrent == true)

感谢Panagiotis Kanavos的建议。