Linq通过搜索关键字从对象的关系列表中选择对象
Posted
技术标签:
【中文标题】Linq通过搜索关键字从对象的关系列表中选择对象【英文标题】:Linq selecting object from relational list of object by search keyword 【发布时间】:2020-08-14 18:18:17 【问题描述】:我想使用搜索关键字获取学校校长。学校 可以有一个用户列表,其中一个是主要角色。
现在我的问题是我正在实现一个自动搜索,它需要 关键字并根据学校名称、代码和校长进行搜索 名字。
代码:
public class School : AuditableDataEntity<int>
[Required]
[MaxLength(200)]
public string Name get; set;
[MaxLength(150)]
public string Code get; set;
public District District get; set;
public ICollection<UserProfile> Users get; set;
public class UserProfile : AuditableDataEntity<Guid>
[Required]
[MaxLength(100)]
public string FirstName get; set;
[Required]
[MaxLength(100)]
public string LastName get; set;
[Required]
[MaxLength(200)]
public string Email get; set;
[MaxLength(50)]
public string PhoneWork get; set;
[MaxLength(20)]
public int PhoneWorkExt get; set;
[MaxLength(50)]
public string PhoneMobile get; set;
public UserLevel UserLevel get; set;
public UserRole UserRole get; set;
public UserDesignation UserDesignation get; set;
public School School get; set;
public int? SchoolId get; set;
public string FullName => $"FirstName LastName";
Task<Response<IEnumerable<SchooSearchDTO>>> ISchoolQueryService.GetSchoolAutoCompleteData(string searchKeyword)
return _schoolQueryRepository.WithRelatedEntities().Where(x => x.Name.Contains(searchKeyword)
||x.Code.Contains(searchKeyword)
|| x.Users.FirstOrDefault(y => y.DataEntityState == DataEntityState.Published && y.UserDesignation == UserDesignation.Principal).FullName.Contains(searchKeyword)).OrderBy(u => u.Name).Select(z => new SchooSearchDTO
PrincipalName = z.Name,
CDSCode = z.Code
).ToResponseListAsync();
错误:
LINQ 表达式 'DbSet .Where(s => s.Name.Contains(__searchKeyword_0) || s.CDSCode.Contains(__searchKeyword_0) || DbSet .Where(u => EF.Property>(s, "Id") != null && EF.Property>(s, "Id") == EF.Property>(u, “学校标识”)) .Where(u => (int)u.DataEntityState == 1 && (int)u.UserDesignation == 1) .Select(u => u.FullName) .FirstOrDefault().Contains(__searchKeyword_0))' 无法翻译。要么以可以翻译的形式重写查询, 或通过插入调用显式切换到客户端评估 AsEnumerable()、AsAsyncEnumerable()、ToList() 或 ToListAsync()。见https://go.microsoft.com/fwlink/?linkid=2101038 更多信息。
【问题讨论】:
【参考方案1】:问题在于 EF 无法将其转换为 SQL。
x.Users.FirstOrDefault(y => y.DataEntityState == DataEntityState.Published && y.UserDesignation == UserDesignation.Principal).FullName.Contains(searchKeyword)
所以尝试使用Any
而不是在LINQ 中选择带有FirstOrDefault
的用户,以便EF 能够将其翻译成SQL。
Task<Response<IEnumerable<SchooSearchDTO>>> ISchoolQueryService.GetSchoolAutoCompleteData(string searchKeyword)
return _schoolQueryRepository.WithRelatedEntities().Where(x => x.Name.Contains(searchKeyword)
||x.Code.Contains(searchKeyword)
|| x.Users.Any(y => y.DataEntityState == DataEntityState.Published && y.UserDesignation == UserDesignation.Principal && y.FirstName.Contains(searchKeyword))
).OrderBy(u => u.Name).Select(z => new SchooSearchDTO
PrincipalName = z.Name,
CDSCode = z.Code
).ToResponseListAsync();
见:The LINQ expression could not be translated and will be evaluated locally
编辑:
您还需要使用FirstName
,因为FullName
是您在SQL 中没有的属性。
【讨论】:
同样的错误,需要寻找其他方法。 它通过更改 && y.FirstName.Contains(searchKeyword) 起作用,问题是与 FullName 相关的,因此它通过更改为 Any 并将 FullName 更改为 FirstName 来起作用。 是的,好点,我忘了提到..我已经更新了我的答案。以上是关于Linq通过搜索关键字从对象的关系列表中选择对象的主要内容,如果未能解决你的问题,请参考以下文章
将关键字存储在查询集中,在结果查询集中提供带有 Q 对象的搜索命中以及搜索结果