Linq通过搜索关键字从对象的关系列表中选择对象
Linq selecting object from relational list of object by search keyword
I want to get the Principal of School using a search keyword. Schools
can have list of users from which one is of a principal role.
Now my problem is I am implementing an auto search that takes a
keyword and searches on the basis for School Name, Code, and principal
name.
代码:
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();
}
错误:
The LINQ expression '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,
"SchoolId"))
.Where(u => (int)u.DataEntityState == 1 && (int)u.UserDesignation == 1)
.Select(u => u.FullName)
.FirstOrDefault().Contains(__searchKeyword_0))' 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
either AsEnumerable(), AsAsyncEnumerable(), ToList(), or
ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for
more information.
问题在于 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.
中没有
I want to get the Principal of School using a search keyword. Schools can have list of users from which one is of a principal role.
Now my problem is I am implementing an auto search that takes a keyword and searches on the basis for School Name, Code, and principal name.
代码:
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();
}
错误:
The LINQ expression '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, "SchoolId")) .Where(u => (int)u.DataEntityState == 1 && (int)u.UserDesignation == 1) .Select(u => u.FullName) .FirstOrDefault().Contains(__searchKeyword_0))' 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 either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
问题在于 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.