使用EF Core 2.1继承进行过滤 [英] Filtering with EF Core 2.1 inheritance

查看:90
本文介绍了使用EF Core 2.1继承进行过滤的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to find a way to filter my results in EF Core 2.1, when using inherited objects.

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

I've got a base model and several inherited classes (but I've just included one):

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

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

LikeType is an enum which is defined as the discriminator in the dbcontext. Every Document has a boolean property .IsCurrent.

要从数据库中获取所有项目,我正在使用类似这样的查询:

To get all items from the database, I'm using a query like:

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)

这很漂亮,可以返回所有带有所包含子对象的对象,而不会出现任何错误.我想做的是从链接文档具有.IsCurrent == true的数据库中获取所有项目.我尝试将以下内容添加到上面的查询中,但两者均导致异常:

This works beautifully, and returns all objects with the included sub-objects without any error. What I'm trying to do, is to get all items from the database for which the linked document has .IsCurrent == true. I've tried adding the following to the query above, but both result in an exception:

.Where(x => (x as DocumentLike).Document.IsCurrent == true)

并且:

.Where(x => x.LikeType == LikeType.Document ? (x as DocumentLike).Document.IsCurrent == true : true) 

执行查询时引发的异常:

The exception, which is thrown when I'm executing the query:

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)

有没有办法做到这一点?

Is there a way to do this?

更新: 澄清一下:我正在寻找一个查询,该查询从数据库中返回所有Like对象,而不管它们的(子)类型如何.如果子类型是DocumentLike,我只希望链接到具有.IsCurrent == true的文档的对象.

UPDATE: To clarify: I'm looking to get a single query that returns all Like-objects from the database, regardless of their (sub)types. In case the subtype is DocumentLike, I only want the objects that are linked to a document that has .IsCurrent == true.

推荐答案

技巧是编辑谓词,如下所示:

The trick was to edit the predicate a bit, like this:

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

感谢 Panagiotis Kanavos 的建议.

这篇关于使用EF Core 2.1继承进行过滤的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆