C# 动态Linq查询抛出属性X不是类Y的成员

C# 动态Linq查询抛出属性X不是类Y的成员,c#,linq,C#,Linq,我正在尝试使用表达式编写动态LINQ查询(这是第一次),以实现以下目标: public override IQueryable<SelectListDto> GetSelectList() { var ageGroups = DbContext.Set<AgeGroup>() .Select(x => new SelectListDto() { ID = x.ID, Name = x.Description_Chinese }); r

我正在尝试使用表达式编写动态LINQ查询(这是第一次),以实现以下目标:

public override IQueryable<SelectListDto> GetSelectList()
{
    var ageGroups = DbContext.Set<AgeGroup>()
        .Select(x => new SelectListDto() { ID = x.ID, Name = x.Description_Chinese });
    return ageGroups;
}
下面是我的表达代码,我试图根据问题答案中给出的代码进行改编:

protected Func<TEntity, SelectListDto> GetSelectListStatement()
{
    var entityType = typeof(TEntity);
    var entityIDProperty = entityType.GetProperty("ID");
    var entityNameProperty = entityType.GetProperty(GetPropertyNameForSelectListDescription()); // Returns the name of the property on TEntity to map to SelectListDto.Name
    var parameterExpression = Expression.Parameter(typeof(TEntity), "x"); // "x" in x => ..., linked to the TEntity
    var newExpression = Expression.New(typeof(SelectListDto)); // "new SelectListDto()"
    var idMemberExpression = Expression.Property(parameterExpression, entityIDProperty); // "x.ID"
    var nameMemberExpression = Expression.Property(parameterExpression, entityNameProperty); // "x.Name"
    var idBinding = Expression.Bind(entityIDProperty, idMemberExpression); // "ID = x.ID"
    var nameBinding = Expression.Bind(entityNameProperty, nameMemberExpression); // "Name == x.Name"
    var bindings = new List<MemberAssignment>() { idBinding, nameBinding };
    var memberInitExpression = Expression.MemberInit(newExpression, bindings); // initialization "new SelectListDto { ID = x.ID, Name = x.Name }"
    var lambda = Expression.Lambda<Func<TEntity, SelectListDto>>(memberInitExpression, parameterExpression); // // expression "x => new SelectListDto { ID = x.ID, Name = x.Name }"
    return lambda.Compile();
}
protectedfunc GetSelectListStatement()
{
var entityType=类型(TEntity);
var entityIDProperty=entityType.GetProperty(“ID”);
var entityNameProperty=entityType.GetProperty(GetPropertyNameForSelectListDescription());//返回要映射到SelectListDto.name的属性的名称
var parameterExpression=Expression.Parameter(typeof(tenty),“x”);/“x”在x=>…,链接到tenty
var newExpression=Expression.New(typeof(SelectListDto));/“New SelectListDto()”
var idMemberExpression=Expression.Property(parameterExpression,entityIDProperty);/“x.ID”
var namemberexpression=Expression.Property(parameterExpression,entityNameProperty);/“x.Name”
var idBinding=Expression.Bind(entityIDProperty,idMemberExpression);/“ID=x.ID”
var nameBinding=Expression.Bind(entityNameProperty,nameMemberExpression);/“Name==x.Name”
var bindings=new List(){idBinding,nameBinding};
var memberInitExpression=Expression.MemberInit(newExpression,bindings);//初始化“new SelectListDto{ID=x.ID,Name=x.Name}”
var lambda=Expression.lambda(memberInitExpression,parameterExpression);///表达式“x=>newselectlistdto{ID=x.ID,Name=x.Name}”
返回lambda.Compile();
}
但是这段代码抛出了异常

“ID”不是“SelectListDto”类型的成员

我似乎很清楚ID是SelectList的成员。所以我在这一点上被难住了

编辑:

以下是Asad引导解决方案后的代码:

protected Func<TEntity, SelectListDto> GetSelectListStatement()
{
    var entityType = typeof(TEntity);
    var selectListDtoType = typeof(SelectListDto);
    var entityIDProperty = entityType.GetProperty("ID");
    var entityNameProperty = entityType.GetProperty(GetPropertyNameForSelectListText());
    var selectListDtoIDProperty = selectListDtoType.GetProperty("ID");
    var selectListDtoNameProperty = selectListDtoType.GetProperty("Name");

    var parameterExpression = Expression.Parameter(entityType, "x");
    var newInstantiationExpression = Expression.New(selectListDtoType);

    var idMemberExpression = Expression.Property(parameterExpression, entityIDProperty);
    var nameMemberExpression = Expression.Property(parameterExpression, entityNameProperty);

    var idBinding = Expression.Bind(selectListDtoIDProperty, idMemberExpression);
    var nameBinding = Expression.Bind(selectListDtoNameProperty, nameMemberExpression);
    var bindings = new List<MemberAssignment>() { idBinding, nameBinding };

    var memberInitExpression = Expression.MemberInit(newInstantiationExpression, bindings);
    var lambda = Expression.Lambda<Func<TEntity, SelectListDto>>(memberInitExpression, parameterExpression);
    return lambda.Compile();
}
protectedfunc GetSelectListStatement()
{
var entityType=类型(TEntity);
var selectListDtoType=typeof(SelectListDto);
var entityIDProperty=entityType.GetProperty(“ID”);
var entityNameProperty=entityType.GetProperty(GetPropertyNameForSelectListText());
var selectListDtoIDProperty=selectListDtoType.GetProperty(“ID”);
var selectListDtoNameProperty=selectListDtoType.GetProperty(“名称”);
var parameterExpression=Expression.Parameter(entityType,“x”);
var New实例化Expression=Expression.New(selectListDtoType);
var idMemberExpression=Expression.Property(parameterExpression,entityIDProperty);
var namemberexpression=Expression.Property(parameterExpression,entityNameProperty);
var idBinding=Expression.Bind(selectListDtoIDProperty,idMemberExpression);
var nameBinding=Expression.Bind(selectListDtoNameProperty,nameMemberExpression);
var bindings=new List(){idBinding,nameBinding};
var memberInitExpression=Expression.MemberInit(new实例化表达式,绑定);
var lambda=Expression.lambda(memberInitExpression,parameterExpression);
返回lambda.Compile();
}

我将删除一些额外的内容,以便更容易发现问题:

// Get PropertyInfo from TEntity
var entityIDProperty = entityType.GetProperty("ID");

...

// Create an instantiation expression for SelectListDto
var newExpression = Expression.New(typeof(SelectListDto));

...

// Create a member initialization expression for TEntity's ID property
var idBinding = Expression.Bind(entityIDProperty, idMemberExpression);

...

// Try to instantiate an SelectDto with an initializer 
// that initializes TEntity's ID property. This makes no sense!
var memberInitExpression = Expression.MemberInit(newExpression, bindings);
正如您在上面所看到的,具有绑定表达式的属性与正在实例化的类型之间存在不匹配

解决方案取决于你想做什么。您返回的func的签名有点古怪,因为您所做的操作与创建具有该签名的func所需的操作完全相反。您正在创建一个func,该func接受一个
TEntity
,并返回一个新的
SelectListDto
(尽管如上所述,您没有正确执行此操作)。当编译为lambda时,这将是
Func
,而不是
Func

如果确实要返回
Func
,则需要将类型为
SelectListDto
的参数表达式和类型为
TEntity
的实例化表达式设置为,这样就可以了


另一方面,如果你想返回一个
Func
,你需要将
entityIDProperty
entityNameProperty
更改为
SelectListDto
的属性,它说的是
SelectList
不是
SelectListDto
?为什么你的类有名称,但你引用的是中文描述。这是错误的代码吗?抛出异常的是哪一行?细节越多越好。对不起,“SelectList”是一个输入错误,应该一直是“SelectListTo”。至于名称与描述,中文的名称应该是通用的。当我发布时,我更改了代码以转移注意力。但我会把原件放回去,因为它更有意义。SelectListDto.Name在这种特殊情况下应该映射到中文描述。虽然我很感激您尝试使其通用,但如果代码无效,则很难发现“真正”的问题。非常感谢您,Asad。您的回答帮助我了解了代码中的错误。成员表达式用于tenty,绑定需要用于SelectListDto属性。
// Get PropertyInfo from TEntity
var entityIDProperty = entityType.GetProperty("ID");

...

// Create an instantiation expression for SelectListDto
var newExpression = Expression.New(typeof(SelectListDto));

...

// Create a member initialization expression for TEntity's ID property
var idBinding = Expression.Bind(entityIDProperty, idMemberExpression);

...

// Try to instantiate an SelectDto with an initializer 
// that initializes TEntity's ID property. This makes no sense!
var memberInitExpression = Expression.MemberInit(newExpression, bindings);