LINQ表达式无法翻译错误

kpbwa7wx  于 5个月前  发布在  其他
关注(0)|答案(3)|浏览(101)

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

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

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

public class Authority
{
    public int Id { get; set; }
    public string AuthorityOf { get; set; }
}

public class Request
{
    public int Id { get; set; }
    [JsonField]
    public List<string> RequiresAuthorityFrom { get; set; }
}


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

The LINQ expression 'a => DbSet<Authority>()
    .Select(a => a.AuthorityOf)
    .Any(p => object.Equals(
        objA: p, 
        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#

首先,我会改变这一点:

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

字符串
对此:

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


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

erhoui1w

erhoui1w2#

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

public class Request
{
    public int Id { get; set; }
    public string RequiresAuthorityFrom { get; set; }
}

字符串
并将查询重写为:

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#

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

var distinctAuthorities = _dbContext.Authorities.Select(auth => auth.AuthorityOf).Distinct();

var result = _dbContext.Requests
    .Where(req => req.RequiresAuthorityFrom.Any(a => distinctAuthorities.Contains(a)))
    .ToList();

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

相关问题