【问题标题】:Get entity by field value in ASP.NET Core 3.1在 ASP.NET Core 3.1 中按字段值获取实体
【发布时间】:2019-12-18 05:17:05
【问题描述】:

我以前使用过这样的方法来检索实体,它在 ASP.NET Core 2.2 存储库中运行良好(因为我的大多数表都有 CODE属性):

public T GetByCode(string code)
{
      PropertyInfo pi = typeof(T).GetProperty("Code");
      return _context.Set<T>().FirstOrDefault(t => pi.GetValue(t).ToString().Trim().ToLower() == code.Trim().ToLower());
}


但是,当我将框架更改为 .NET Core 3.1 时,我得到了如下错误:

InvalidOperationException:LINQ 表达式 'DbSet .Where(c => __pi_0.GetValue(c).ToString().Trim().ToLower() == __ToLower_1)' 无法翻译。要么重写查询的形式,可以 被翻译,或通过插入显式切换到客户端评估 调用 AsEnumerable()、AsAsyncEnumerable()、ToList() 或 ToListAsync()。

【问题讨论】:

  • so 错误告诉您问题出在哪里以及该怎么做。问题是什么?
  • 这是问题的一部分,我不知道如何将查询重写为 AsEnumerable() 和其余部分
  • @fenixil:这是个糟糕的建议,因为 where 将在内存中进行评估;因此;首先获取整个数据集。所以你的“评论”只对一小部分用例有帮助。
  • @Mertez:如果您的数据集足够小,请在 where 之前使用“ToListAsync”。如果不;可以将字符串转换为 SQL 的 google。有许多;你也有那些,但语法不同。另请注意:SQL 中的字符串比较通常是大小写不变的。
  • 我发现了一个类似我的问题,但不是@daniel-hilgarth link 的确切答案

标签: c# asp.net-core linq-to-sql entity-framework-core repository-pattern


【解决方案1】:

因为在 EF Core 2.2 中,您可能会将整个表提取到内存中。

在您的情况下,由于所有这些表都有Code 属性,我建议添加某种形式的IHaveCode 通用接口。然后您可以轻松删除所有反射,EF Core 无法转换为 sql;

public T GetByCode<T>(string code) where T:IHaveCode
{
      return _context.Set<T>().FirstOrDefault(t => t.Code.Trim().ToLower() == code.Trim().ToLower());
}

【讨论】:

  • 谢谢@jeremy-lakeman 这个界面“IHaveCode”是什么样的?
  • 我的意思是,您在这些类型上拥有的任何公共属性都应该由公共基本类型或接口表示。例如interface ICommon{ string Code { get; set; }}。你怎么称呼它,或者你包括什么取决于你。
  • 我已经有一个基类,Id和Code来自基类
  • @Mertez:尝试用谷歌搜索转化;我不知道它们,但如果您使用System.Convert 的变体,可能会翻译成正确的SQL。有一个列表,但因为我在手机上,我没有机会搜索它。
  • 所以你可以where T:BaseClass
猜你喜欢
  • 1970-01-01
  • 2020-10-24
  • 2021-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-11
  • 2021-08-08
  • 1970-01-01
相关资源
最近更新 更多