DynamicallyBuildSelectListsfromLinqtoEntityQuery我正在寻找一种从iQueryable对象动态创建选择列表的方法。具体的例子,我想做类似下面的事情::SelectList.add(e=>e.UserType);休息;case"Name":SelectList.add(e=>e.Name);休息;等等....}}varselectResult=(fromuinentitiesselectobjSelectList);所以所有属性都是已知的,但我事先不知道要选择哪些属性。这将通过列参数传递。我知道我将在SelectResult类型上遇到问题,因为当Select列表是动态时,编译器不知道匿名类型的属性需要什么。如果以上不可能:我需要的场景如下:我正在尝试创建一个可以实现显示分页/过滤数据列表的类。这些数据可以是任何东西(取决于实现)。使用的linq是实体的linq。所以他们直接链接到sql数据。现在我只想选择我实际显示在列表中的实体的列。因此我希望选择是动态的。我的实体可能有一百个属性,但如果列表中只显示3个,我不想生成一个选择所有100列数据然后只使用其中3列的查询。如果有我没有想到的不同方法,我愿意接受编辑:关于约束的一些说明:-查询需要对实体使用linq(参见问题主题)-一个实体可能包含100列,所以选择全部列然后只阅读我需要的列不是一个选项。-最终用户决定显示哪些列,因此要选择的列是在运行时确定的-我需要创建一个SINGLEselect,具有多个select语句意味着对数据库进行多个查询,这是一个动态选择表达式,我没有可以使用Expression.MemberInit方法轻松构建编译时已知类型的表达式,其中使用Expression.Bind方法创建MemberBinding。这是一个执行以下操作的自定义扩展方法:varresultType=typeof(TResult);varparameter=Expression.Parameter(sourceType,"e");varbindings=columns.Select(column=>Expression.Bind(resultType.GetProperty(column),Expression.PropertyOrField(parameter,column)));varbody=Expression.MemberInit(Expression.New(resultType),bindings);varselector=Expression.Lambda(body,parameter);returnsource.Provider.CreateQuery(Expression.Call(typeof(Queryable),"Select",newType[]{sourceType,resultType},source.Expression,Expression.Quote(selector)));唯一的问题是什么是TResult类型。在EFCore中,您可以传递实体类型(如EntityModel.Core.User中的EntityModel.Core.User),它将起作用。在EF6及更早版本中,您需要一个单独的非实体类型,否则您将收到NotSupportedException-无法在LINQtoEntities查询中构造实体或复杂类型。更新:如果你想删除字符串列,我建议你用下面的类替换扩展方法:publicclassSelectList{privateListmembers=newList();publicSelectListAdd(Expression>selector){varmember=((MemberExpression)selector.Body).Member;成员。添加(成员);归还这个;}publicIQueryableSelect(IQueryablesource){varsourceType=typeof(TSource);varresultType=typeof(TResult);varparameter=Expression.Parameter(sourceType,"e");varbindings=members.Select(member=>Expression.Bind(resultType.GetProperty(member.Name),Expression.MakeMemberAccess(parameter,member)));varbody=Expression.MemberInit(Expression.New(resultType),bindings);varselector=Expression.Lambda>(body,parameter);返回源。选择(选择器);示例用法:varselectList=newSelectList();selectList.Add(e=>e.UserType);selectList.Add(e=>e.Name);varselectResult=selectList.Select(实体);你想要的是可能的,但不是微不足道的。您可以使用System.Linq.Expressions命名空间中的方法和类动态构建EF查询。有关如何动态构建Select表达式的一个很好的示例,请参阅此问题。我相信这就是你所需要的:varentities=newList();entities.Add(newUser{Name="First",Type="TypeA"});entities.Add(newUser{Name="Second",Type="TypeB"});字符串[]列={“名称”,“类型”};varselectResult=new列表();foreach(varcolumnIDincolumns){selectResult.AddRange(entities.Select(e=>e.GetType().GetProperty(columnID).GetValue(e,null).ToString()));}foreach(varresultinselectResult){Console.WriteLine(result);}此代码输出:更新(根据评论)//初始化实体列表(用户)varentities=newList();entities.Add(newUser{Name="First",Type="TypeA",SomeOtherField="abc"});entities.Add(newUser{Name="Second",Type="TypeB",SomeOtherField="xyz"});//设置需要的字段string[]columns={"Name","Type"};//通过所需字段集创建User类的一组属性varproperties=typeof(User).GetProperties().Where(p=>columns.Contains(p.Name)).ToList();//单次sel获取ect(通过使用Dynamic对象)varselectResult=entities.Select(e=>{dynamicx=newExpandoObject();vartemp=xasIDictionary;foreach(属性中的var属性)temp.Add(property.Name,property.GetValue(e));返回x;});//迭代结果foreach(varresultinselectResult){Console.WriteLine(result.Name);Console.WriteLine(result.Type);}这段代码输出:以上是C#学习教程:从linq到entityquery动态构建选择列表,分享所有内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
