如果在查询上使用.Count()
方法,那么执行需要显式包含导航属性的过滤的查询将不会加载它们。在Where()
子句中的过滤表达式运行时导致异常。
然而,将.Count()
更改为.ToList()
会使实体框架包含引用的导航属性并生成正确的结果
似乎Count()
方法忽略导航属性,并且过滤表达式中的值为null
我的项目正在使用ASP Net Core 1.1和EntityFramework 1.1.4
public class ItemsService : IItemsService
{
private readonly ApplicationDbContext dbContext;
public ItemsService(ApplicationDbContext dbContext)
{
this.dbContext = dbContext;
}
public ISearchResult Search(ISearchOptions options)
{
var query = this.dbContext.Item
.Include(i => i.Vehicle)
.Include(x => x.Part).ThenInclude(p => p.PartCategory)
.Where(i => i.IsDeleted == false);
query = this.ApplyMakeFiltering(query, options.Make);
query = this.ApplyModelFiltering(query, options.Model);
var total = query.Count(); // Throws => NavigationProperty Vehicle is null
var total2 = query.ToList().Count; // Works Correctly
return new SearchResult(options, query, total);
}
private IQueryable<Item> ApplyMakeFiltering(IQueryable<Item> query, string make)
{
return this.Filter(
query,
make, // item.Vehicle is null for `Count()` but set correctly for `ToList()`
item => this.StringMatches(item.Vehicle.CustomVehicleMakeName, make));
}
private IQueryable<Item> ApplyModelFiltering(IQueryable<Item> query, string model)
{
return this.Filter(
query,
model,
item => this.StringMatches(item.Vehicle.CustomVehicleModelName, model));
}
private IQueryable<Item> Filter<T>(IQueryable<Item> query, T expected, Predicate<Item> matcher)
{
if (expected == null) return query;
return query.Where(item => matcher(item));
}
private bool StringMatches(string a, string b)
{
if (String.IsNullOrEmpty(a)) return false;
return a.Equals(b, StringComparison.OrdinalIgnoreCase);
}
}
过滤后获得匹配结果计数的正确方法是什么?