linq - LINQ 通用 IQueryableWHERE 子句
问题描述
假设我有一个带有 3 个 DBSet 的 DBContext:
public class DatabaseContext : DbContext
{
public DbSet<A> As { get; set; }
public DbSet<B> Bs { get; set; }
public DbSet<C> Cs { get; set; }
}
class A
{
public string Text { get; set; }
public string Code { get; set; }
}
class B
{
public string Name { get; set; }
public string Code { get; set; }
}
class C
{
public string Book { get; set; }
public string Code { get; set; }
}
我想编写一个通用方法:
- 通常将三个中的任何一个
DbSet
作为第一个参数 - 将字符串值作为第二个参数
- 不强制转换为,返回提供的字段与提供的字符串匹配的
IEnumerable
第一条记录DbSet
Code
到目前为止,我有这个方法:
public static T GetCode<T>(IQueryable<T> set, string code) where T : class
{
var Prop = typeof(T).GetProperty("Code");
return set.Where(x => (string)Prop.GetValue(x) == code).FirstOrDefault();
}
当我尝试使用此行调用它时:
var _A = GetCode(TheDB.As, "123");
var _B = GetCode(TheDB.Bs, "123");
var _C = GetCode(TheDB.Cs, "123");
我收到此错误:
无效操作异常:
无法翻译 LINQ 表达式 'DbSet<A>.Where(m => (string)__Prop_0.GetValue(m) == __code_1)'。
以可翻译的形式重写查询,或通过插入对 AsEnumerable()、AsAsyncEnumerable()、ToList() 或 ToListAsync() 的调用显式切换到客户端评估。
我怎样才能写出能够正确翻译的WHERE
子句?如果我将 转换为 ,我的方法有效,但我不想这样做,因为该集合可能非常大,我希望数据库(而不是我的应用程序)进行记录搜索。DbSet
IQueryable
IQueryable
IEnumerable
解决方案
最简单(并且类型安全)的方法是只创建一个类似的接口IHaveCode
并将泛型参数限制为它:
interface IHaveCode
{
string Code { get; set; }
}
class A: IHaveCode
{
public string Text { get; set; }
public string Code { get; set; }
}
class B: IHaveCode
{
public string Name { get; set; }
public string Code { get; set; }
}
class C: IHaveCode
{
public string Book { get; set; }
public string Code { get; set; }
}
public static T GetCode<T>(IQueryable<T> set, string code) where T : IHaveCode
{
return set.Where(x => x.Code == code).FirstOrDefault();
}
如果由于某种原因它不适合您,那么您将需要自己构建一个表达式树。
推荐阅读
- swift - 如何在 Swift 中使用 Alamofire ppost 请求将 UIImage 扩展作为参数发送到服务器?
- git - git 和 Github CLI 或 gh 有什么区别?
- java - SolrClient 即使在传递套接字超时参数后也不会超时
- python - ParseError:错误标记数据。C 错误:捕获缓冲区溢出 - 可能是格式错误的输入文件。(read_csv)
- angular - 如何检测Angular Material Autocomplete组件中的滚动位置
- linux - 使用 AWK 将浮点数转换为用户定义的输出
- pyspark - PySpark:如何在不同的键上连接两个表并从每个表中获取所有列?
- css - 不能将额外的参数传递给 CSS Houdini 绘制函数?
- javascript - 按名称动态调用类(字符串到类名)
- python - 我怎样才能创建一组重复的条纹,就像在美国国旗中一样