LINQ表达式无法翻译错误

kpbwa7wx  于 2024-01-03  发布在  其他
关注(0)|答案(3)|浏览(263)

我有一个数据库,其中有两个表,Requests和Authorities。Authorities有一个名为AuthorityOf的列,其中包含一个字符串,如“AAAA”,Requests表中的每个请求都有一个名为AuthorityFrom的列,其中包含一个List,如[“AAAA”,“BBBB”,“CCCC”](在数据库中存储为字符串,并作为List检索)。我正在尝试编写一个LINQ查询,以从Requests表中获取所有请求,其中列表AuthorityFrom包含Authorities表中AuthorityOf列中的任何字符串。
我写了一个这样的查询:

  1. var result = _dbContext.Requests
  2. .Where(req => req.RequiresAuthorityFrom.Any(a => _dbContext.Authorities.Select(auth => auth.AuthorityOf).Contains(a)))
  3. .ToList();

字符串
实体类型如下(简化版本):

  1. public class Authority
  2. {
  3. public int Id { get; set; }
  4. public string AuthorityOf { get; set; }
  5. }
  6. public class Request
  7. {
  8. public int Id { get; set; }
  9. [JsonField]
  10. public List<string> RequiresAuthorityFrom { get; set; }
  11. }


来自包Innofactor.EfCoreJsonValueConverter的JsonField标志用于处理getter和setter中json与json之间的转换。
它返回以下错误:

  1. The LINQ expression 'a => DbSet<Authority>()
  2. .Select(a => a.AuthorityOf)
  3. .Any(p => object.Equals(
  4. objA: p,
  5. objB: a))' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.


如何编写这样的查询呢?我试过通过插入对AsEList/ToList的调用来切换到客户端计算,但没有什么区别。

t98cgbkg

t98cgbkg1#

首先,我会改变这一点:

  1. var result = _dbContext.Requests.Where(req => req.RequiresAuthorityFrom.Any(a => _dbContext.Authorities.Select(auth => auth.AuthorityOf).Contains(a))).ToList();

字符串
对此:

  1. var result = _dbContext.Requests.Where(req => req.RequiresAuthorityFrom.Any(a => _dbContext.Authorities.Any(auth => auth.AuthorityOf == a))).ToList();


如果不能翻译(因为不确定JsonField属性是如何处理的),那么我会考虑客户端评估。
但是,正如在评论中提到的,用不应该在那里的东西装饰实体是一个坏主意。

erhoui1w

erhoui1w2#

我通过根据注解修改实体来解决它,如下所示:

  1. public class Request
  2. {
  3. public int Id { get; set; }
  4. public string RequiresAuthorityFrom { get; set; }
  5. }

字符串
并将查询重写为:

  1. var result = _dbContext.Requests.Where(x => _dbContext.Authorities.Select(a => a.AuthorityOf).Any(a => x.RequiresAuthorityFrom.Contains(a))).OrderBy(x => x.Id).ToList();

mrwjdhj3

mrwjdhj33#

如果你先尝试获取所有不同的权限会怎么样?假设它们的数量是有限的:

  1. var distinctAuthorities = _dbContext.Authorities.Select(auth => auth.AuthorityOf).Distinct();
  2. var result = _dbContext.Requests
  3. .Where(req => req.RequiresAuthorityFrom.Any(a => distinctAuthorities.Contains(a)))
  4. .ToList();

字符串
通过获取不同的权限来过滤请求,您可能会减少数据库查询的数量并提高性能。

相关问题