【发布时间】:2020-10-31 16:51:12
【问题描述】:
给定两个实体 EntityOne 和 EntityTwo:
public class EntityOne
{
public string Title { get; set; }
public bool IsSomething { get; set; }
}
public class EntityTwo
{
...
public virtual IEnumerable<EntityOne> EntityOnes { get; set; }
}
还有一个EntityOneFilter 对象,例如:
public class EntityOneFilter
{
public EntityOneFilter(string? query, bool? isSomething, ...)
{
...
}
public string? Query { get; }
public bool? IsSomething { get; }
}
我想重用可以同时应用于IEnumerable<EntityOne> 和IQueryable<EntityOne> 的查询逻辑:
(filter.Query == null || EF.Functions.Like(entity.Title, $"%{filter.Query}%"))
&& (!filter.IsSomething.HasValue || entity.IsSomething == filter.IsSomething.Value)
&& ...
这样它就可以应用于来自DbContext的IQueryables:
dbContext.EntityOnes.Where(<something with filter>).FirstAsync();
还有IEnumerable<EntityOne>,它显示为EntityTwo的一对多集合:
dbContext.EntityTwos
.Where(e2 => e2.EntityOnes.Where(<something with filter>).Any())
.FirstAsync();
我怎样才能做到这一点?
【问题讨论】:
-
您是否尝试过使用
entity.Title.Contains(filter.Query)?此外,您应该将filter.Query和filter.IsSomething分配给要在查询中使用的局部变量,这样EF 就不会抱怨翻译EntityOneFilter。 -
@juharr 感谢
.Contains提示。目前,它似乎根本没有抱怨这一点。它将它们翻译为好像它们是两个自变量一样。但是,是的,表达本身不是问题。它按预期工作。 -
我觉得你应该看看Linqkit,例如从here开始。
-
我所做的是使用
.AsEnumerable()方法将 IQueryable 转换为 IEnumerable。然后我将该结果传递给其他各种类以增强过滤器。那是可行的吗? -
您可以通过 AsQueryable 方法将 IEnumerable 转为 IQueryable。但无论如何,它不适用于仅针对 SQL 翻译的 EF.Functions。
标签: c# linq .net-core entity-framework-core npgsql