C# EF Core multiple";其中;没有翻译

C# EF Core multiple";其中;没有翻译,c#,.net-core,entity-framework-core,C#,.net Core,Entity Framework Core,我有一个db模型,我想在运行时根据不同的属性进行过滤。为此,我有一些方法,每个方法根据属性运行一个“where”子句,并返回一个IQueryable。问题是,该子句无法转换为SQL,因此查询运行时没有“WHERE”语句,返回整个表,而服务器正在进行过滤,这既慢又昂贵 从日志中,我得到一条消息: Microsoft.EntityFrameworkCore.Query:警告:LINQ表达式 “其中(新EntityId([ed].EntityId).Id==\uEntityId\uId\u1)”无法

我有一个db模型,我想在运行时根据不同的属性进行过滤。为此,我有一些方法,每个方法根据属性运行一个“where”子句,并返回一个IQueryable。问题是,该子句无法转换为SQL,因此查询运行时没有“WHERE”语句,返回整个表,而服务器正在进行过滤,这既慢又昂贵

从日志中,我得到一条消息:

Microsoft.EntityFrameworkCore.Query:警告:LINQ表达式 “其中(新EntityId([ed].EntityId).Id==\uEntityId\uId\u1)”无法 将进行翻译,并在当地进行评估

我的问题是:我在这条路上走对了吗?如果是的话,我下一步该去哪里

主要功能

public static EntityDataDTO GetEntityByKey(此IQueryable查询,IEntityId entityId,EntityTypeDTO type,字符串键)
{
返回查询
.HasEntity(entityId)
.HasType(类型)
.HasKey(key)
.FirstOrDefault();
}
公共静态EntityDataDTO GetEntity(此IQueryable查询,IEntityId entityId,EntityTypeDTO类型)
{
返回查询
.HasEntity(entityId)
.HasType(类型)
.FirstOrDefault();
}
子功能

公共静态IQueryable HasType(此IQueryable查询,EntityTypeDTO类型)
{
返回query.Where(ed=>ed.Type==Type);
}
公共静态IQueryable HasEntity(此IQueryable查询,IEntityId entityId)
{
返回query.Where(ed=>ed.EntityId.Id==EntityId.Id);
}
全部

公共类实体到
{
公共int Id{get;set;}
公共EntityTypeDTO类型{get;set;}
公共字符串密钥{get;set;}
公共字符串值{get;set;}
公共IEntityId EntityId{get;set;}
公共IPartnerId PartnerId{get;set;}
}

您可以使用表达式谓词并构建一个通用可重用表达式库。下面是将其添加到EntityDTO的示例,请注意,它返回的是一个表达式,而不是实际的IQueryable/IEnumerable:

public partial class EntityDTO
{
  public static Expression<Func<EntityDTO, bool>> HasType(EntityTypeDTO type)
  {
    return ed => ed.Type == type;
  }
  public static Expression<Func<EntityDTO, bool>> HasEntity(IEntityId entityId)
  {
      return ed => ed.EntityId.Id == entityId.Id;
  }
}
public分部类EntityDTO
{
公共静态表达式HasType(EntityTypeDTO类型)
{
返回ed=>ed.Type==Type;
}
公共静态表达式HasEntity(IEntityId entityId)
{
返回ed=>ed.EntityId.Id==EntityId.Id;
}
}

我认为您发布的任何代码都没有问题。但是,您忽略了发布您的
HasKey
方法的定义,因此我假设问题确实存在


在任何情况下,警告都会准确地告诉您问题代码是什么:
newentityid(ed.EntityId).Id
。找到这段代码并更正它。类似于对新类型的调用不能转换为SQL,所以EF必须在内存中运行。从技术上讲,您可以继续并允许EF这样做。但是,这通常表明您将运行效率低下的查询,因此您应该寻找一种更好的方法,不必在内存中运行该部分查询。

考虑将条件转换为表达式,并使用Where子句。查看Show your
EntityDTO
classe为什么要将DTO用作实体?!DTO=域传输对象,其中实体(与EF Core/ORMs一起)表示数据库结构。不清楚您试图实现什么最有可能的问题是接口
IEntityId
-EF(核心)与接口(与集合相关的除外)或“值对象”不兼容。这不是问题所在。OP正在使用
IQueryable
上的扩展,这是这种基于表达式的方法的替代方法,但同样可行。@ChrisPratt同意。考虑到OP使用DTO,两者都是可行的。但表达方法不是最佳实践吗?特别是如果在数据访问代码中实现的话?不一定,尤其是因为这些类似乎命名错误。如果要查询它们,那么它们是实体,而不是DTO,当然也不是域对象。所以,这可以归结为简单的查询扩展。谢谢克里斯的建议!这正是我的问题。它按原样工作,但效率非常低,随着应用程序的发展,这将是一个很大的倒退。