EF不允许在查询中使用非原始类型,因为它们无法转换为SQL。如果尝试,可能会遇到相同的异常:
'无法创建类型的常量值'SomeType'。只有原始的上下文中支持类型或枚举类型。'
我的问题是下面的代码还有什么其他选择:
public class SkillFilter
{
public IEnumerable<EmployeeSkill> TargetSkills { get; set; }
public IQueryable<Employee> Filter(IQueryable<Employee> employees)
{
return employees.Where(employee =>
TargetSkills.Any(targetSkill => employee.Skills
.Any(empSkill =>
empSkill.SkillId == targetSkill.SkillId &&
empSkill.Proficiency == targetSkill.Proficiency)));
}
}
public class EmployeeSkill
{
public Guid Id { get; set; }
public Guid EmployeeId { get; set; }
public Employee Employee { get; set; }
public Guid SkillId { get; set; }
public Skill Skill { get; set; }
public SkillProficiency? Proficiency { get; set; }
}
public enum SkillProficiency
{
Basic = 1,
Novice = 2,
Intermediate = 3,
Advanced = 4,
Expert = 5
}
我需要从Skills
属性中找到至少具有一种技能的所有员工。而且我不能使用原始类型,因为我不仅需要检查技能的ID,还需要检查其熟练程度。
首先-不使用ToList()是选项。我正在尝试寻找一种在数据库而不是内存中对其进行过滤的方法。
我已经尝试过的选项:
1)通过IEqulityComparer使用Contains方法。出现相同的错误
...
return employees.Where(employee =>
TargetSkills.Any(targetSkill =>
employee.Skills.Contains(targetSkill, new EmployeeSkillComparer())));
...
public class EmployeeSkillComparer : IEqualityComparer<EmployeeSkill>
{
public bool Equals(EmployeeSkill x, EmployeeSkill y)
{
return x.SkillId == y.SkillId && x.Proficiency == y.Proficiency;
}
public int GetHashCode(EmployeeSkill obj)
{
return obj.SkillId.GetHashCode();
}
}
...
return from e in employees
where (from empSkill in e.Skills
join targetSkill in TargetSkills
on new {empSkill.SkillId, empSkill.Proficiency} equals
new {targetSkill.SkillId, targetSkill.Proficiency}
select empSkill).Any()
select e;
...
编辑
我对更改属性类型[[熟练程度的建议很少。我在上面的示例中得到的异常表示:
'无法创建类型的常量值'DynamicTargeting.Data.Models.Employees。。只有原始的类型或枚举类型在此上下文中受支持]所以问题不在Profiency中,而是在类[[EmployeeSkill中。熟练程度为[[enum,并将其翻译为EmployeeSkill
int,没有任何问题。但是为了不仅仅依赖异常消息,我将其类型更改为原始类型-int。错误仍然相同。不过,谢谢你们的答复!
我认为最简单的方法(可能不是最有效的,但这里是一般思想)是通过对员工的扩展方法来完成的