C# 无法使用递归func创建类型为error的常量值

C# 无法使用递归func创建类型为error的常量值,c#,linq,entity-framework,recursion,hierarchical-data,C#,Linq,Entity Framework,Recursion,Hierarchical Data,我有一个我运行的查询,它在组织层次结构中按级别对员工进行分组。我想在用户单击组时深入了解这些结果 Employee表如下所示: public class Employee : IEntity { [Key] [DataMember] public int Id { get; set; } [Required] [DataMember] public string Name { get; set; } [DataMembe

我有一个我运行的查询,它在组织层次结构中按级别对员工进行分组。我想在用户单击组时深入了解这些结果

Employee表如下所示:

public class Employee : IEntity
{
    [Key]
    [DataMember]        
    public int Id { get; set; }

    [Required]
    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public int OrganizationEntityId { get; set; }

    [DataMember]
    [ForeignKey("OrganizationEntityId")]
    public virtual OrganizationEntity OrganizationEntity { get; set; }

}
public class OrganizationEntity : IEntity
{
    [KeyAttribute()]
    [DataMember]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; }

    [Required]
    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public int OrganizationEntityTypeId { get; set; }

    [DataMember]
    [ForeignKey("OrganizationEntityTypeId")]
    public virtual OrganizationEntityType OrganizationEntityType { get; set; }

    [DataMember]
    public virtual OrganizationEntity Parent { get; set; }

    public virtual ICollection<OrganizationEntity> Children { get; set; }
}
private IQueryable<Employee> EmployeesByOrganizationLevel(IQueryable<Employee> employees, int orgEntityId)
    {
        Func<Employee, string> selector = (n => this.FindOrganization(n.OrganizationEntity, orgEntityId));

        var result = employees.Where(o => o.OrganizationEntity.Name.Equals(selector));

        return result;
    }

    private string FindOrganization(OrganizationEntity entity, int orgEntityId)
    {
        if (entity == null)
        {
            return null;
        }
        else if (entity.Id == orgEntityId)
        {
            return entity.Name;
        }
        else
        {
            return this.FindOrganization(entity.Parent, orgEntityId);
        }
    }
OrganizationEntity表如下所示:

public class Employee : IEntity
{
    [Key]
    [DataMember]        
    public int Id { get; set; }

    [Required]
    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public int OrganizationEntityId { get; set; }

    [DataMember]
    [ForeignKey("OrganizationEntityId")]
    public virtual OrganizationEntity OrganizationEntity { get; set; }

}
public class OrganizationEntity : IEntity
{
    [KeyAttribute()]
    [DataMember]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; }

    [Required]
    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public int OrganizationEntityTypeId { get; set; }

    [DataMember]
    [ForeignKey("OrganizationEntityTypeId")]
    public virtual OrganizationEntityType OrganizationEntityType { get; set; }

    [DataMember]
    public virtual OrganizationEntity Parent { get; set; }

    public virtual ICollection<OrganizationEntity> Children { get; set; }
}
private IQueryable<Employee> EmployeesByOrganizationLevel(IQueryable<Employee> employees, int orgEntityId)
    {
        Func<Employee, string> selector = (n => this.FindOrganization(n.OrganizationEntity, orgEntityId));

        var result = employees.Where(o => o.OrganizationEntity.Name.Equals(selector));

        return result;
    }

    private string FindOrganization(OrganizationEntity entity, int orgEntityId)
    {
        if (entity == null)
        {
            return null;
        }
        else if (entity.Id == orgEntityId)
        {
            return entity.Name;
        }
        else
        {
            return this.FindOrganization(entity.Parent, orgEntityId);
        }
    }
公共类组织实体:企业
{
[KeyAttribute()]
[数据成员]
[数据库生成(DatabaseGeneratedOption.None)]
公共int Id{get;set;}
[必需]
[数据成员]
公共字符串名称{get;set;}
[数据成员]
公共int OrganizationEntityTypeId{get;set;}
[数据成员]
[ForeignKey(“OrganizationEntityTypeId”)]
公共虚拟组织EntityType组织EntityType{get;set;}
[数据成员]
公共虚拟组织实体父级{get;set;}
公共虚拟ICollection子项{get;set;}
}
我现在用来深入这些组的代码如下所示:

public class Employee : IEntity
{
    [Key]
    [DataMember]        
    public int Id { get; set; }

    [Required]
    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public int OrganizationEntityId { get; set; }

    [DataMember]
    [ForeignKey("OrganizationEntityId")]
    public virtual OrganizationEntity OrganizationEntity { get; set; }

}
public class OrganizationEntity : IEntity
{
    [KeyAttribute()]
    [DataMember]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; }

    [Required]
    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public int OrganizationEntityTypeId { get; set; }

    [DataMember]
    [ForeignKey("OrganizationEntityTypeId")]
    public virtual OrganizationEntityType OrganizationEntityType { get; set; }

    [DataMember]
    public virtual OrganizationEntity Parent { get; set; }

    public virtual ICollection<OrganizationEntity> Children { get; set; }
}
private IQueryable<Employee> EmployeesByOrganizationLevel(IQueryable<Employee> employees, int orgEntityId)
    {
        Func<Employee, string> selector = (n => this.FindOrganization(n.OrganizationEntity, orgEntityId));

        var result = employees.Where(o => o.OrganizationEntity.Name.Equals(selector));

        return result;
    }

    private string FindOrganization(OrganizationEntity entity, int orgEntityId)
    {
        if (entity == null)
        {
            return null;
        }
        else if (entity.Id == orgEntityId)
        {
            return entity.Name;
        }
        else
        {
            return this.FindOrganization(entity.Parent, orgEntityId);
        }
    }
private IQueryable EmployeesByOrganizationLevel(IQueryable employees,intorganityid)
{
Func选择器=(n=>this.FindOrganization(n.OrganizationEntity,orgEntityId));
var result=employees.Where(o=>o.OrganizationEntity.Name.Equals(选择器));
返回结果;
}
私有字符串FindOrganization(OrganizationEntity,int-OrganityId)
{
if(实体==null)
{
返回null;
}
else if(entity.Id==orgEntityId)
{
返回实体名称;
}
其他的
{
返回此.FindOrganization(entity.Parent,orgEntityId);
}
}
传入的员工是我查询中的所有员工减去分组。对于每个记录,我需要遍历层次结构,找出它们是否属于传入的orgEntityId,以便结果中不包括其他组

当我在watch中打开结果变量时,会看到错误消息:

无法创建“System.Func`2[Employee]”类型的常量值。在此上下文中仅支持基元类型或枚举类型

我有非常相似的代码,可以帮我完成分组。主要区别在于我在lambda中使用where而不是GroupBy,所以我不确定为什么会出现这个错误

任何帮助都将不胜感激

更新(查尔斯要求)

这是我目前使用的groupBy代码,所以我现在所做的唯一区别是我使用的是where而不是groupBy:

private IQueryable<HeadCountRecord> GroupEmployeesByOrganizationLevel(IQueryable<Employee> employees, Enums.HeadCountGroupByGroups organizationType)
    {
        Func<Employee, string> selector = (n => this.FindOrganizationByType(n.OrganizationEntity, (int)organizationType));

        var headCount = employees.GroupBy(selector)
                                .Select((o, index) => new HeadCountRecord
                                {
                                    Id = index + 1,
                                    Grouping = o.Key,
                                    HeadCount = o.Count()
                                }).AsQueryable();

        return headCount;
    }

    private string FindOrganizationByType(OrganizationEntity entity, int entityType)
    {
        if (entity == null)
        {
            return null;
        }
        else if (entity.OrganizationEntityTypeId == entityType)
        {
            return entity.Name;
        }
        else
        {
            return this.FindOrganizationByType(entity.Parent, entityType);
        }
    }
private IQueryable GroupEmployeesByOrganizationLevel(IQueryable员工,Enums.HeadCountGroupByGroups组织类型)
{
Func选择器=(n=>this.findorOrganizationByType(n.OrganizationEntity,(int)organizationType));
var员工总数=员工。分组依据(选择器)
.选择((o,索引)=>新编制记录
{
Id=索引+1,
分组=o.键,
人数=o.人数()
}).AsQueryable();
返回人数;
}
私有字符串FindOrganizationByType(OrganizationEntity,int entityType)
{
if(实体==null)
{
返回null;
}
else if(entity.OrganizationEntityTypeId==entityType)
{
返回实体名称;
}
其他的
{
返回此.findorOrganizationByType(entity.Parent,entityType);
}
}

实体框架的LINQ提供程序必须将您的查询转换为SQL。无法将任意函数转换为SQL,这就是错误的意思:EF提供程序只支持
Where
调用中的枚举或基元类型

GroupBy
示例之所以有效,是因为所选方法是
可枚举的.GroupBy
可查询的.GroupBy
(您传递的是
Func
可查询的.GroupBy
扩展方法将采用
表达式)。这就是为什么最后需要调用
AsQueryable()
,因为结果是
IEnumerable


这意味着您的第二种方法将导致Entity Framework加载所有
员工
,并且分组是在内存中完成的,这并不理想。

我最终采用了另一种方法,似乎效果很好

将我以前使用的两种方法更改为:

private IQueryable<Employee> EmployeesByOrganizationLevel(IQueryable<Employee> employees, int orgEntityId)
    {
        var results = new List<Employee>();

        foreach (var employee in employees)
        {
            if (this.FindOrganization(employee.OrganizationEntity, orgEntityId))
            {
                results.Add(employee);
            }    
        }

        return results.AsQueryable();
    }

    private bool FindOrganization(OrganizationEntity entity, int orgEntityId)
    {
        if (entity == null)
        {
            return false;
        }
        else if (entity.Id == orgEntityId)
        {
            return true;
        }
        else
        {
            return this.FindOrganization(entity.Parent, orgEntityId);
        }
    }
private IQueryable EmployeesByOrganizationLevel(IQueryable employees,intorganityid)
{
var results=新列表();
foreach(员工中的var员工)
{
if(this.findorOrganization(employee.OrganizationEntity,OrganityId))
{
结果。添加(员工);
}    
}
返回结果。AsQueryable();
}
私有布尔FindOrganization(OrganizationEntity,int OrganityId)
{
if(实体==null)
{
返回false;
}
else if(entity.Id==orgEntityId)
{
返回true;
}
其他的
{
返回此.FindOrganization(entity.Parent,orgEntityId);
}
}

EF的查询提供程序必须将您的查询转换为SQL。它无法将您的任意
findorOrganization
方法转换为SQL。您能给我们展示一下您所说的
GroupBy
代码吗?我怀疑它是在内存中(在
IEnumerable
上)完成的,而不是作为查询表达式(到
IQueryable
)传递的。我也在努力查看您通过实体递归查看和按名称比较的内容,而不仅仅是返回
员工。其中(e=>e.OrganizationEntityId==OrganityId)
用分组代码更新帖子。那么现在的问题是什么?员工们被链接到