LINQ动态分组我有一个类列表的记录,所以用户可以选择按属性名对行进行动态分组。例如MenuText、RoleName或ActionName。然后我必须执行分组,所以我需要一个通用方法来通过传递列名来处理分组。示例:publicclassMenu{publicstringMenuText{get;set;}publicstringRoleName{get;set;}publicstringActionName{get;set;}}publicclassMenus{varlist=newList();list.Add(新菜单{MenuText="abc",RoleName="Admin",ActionName="xyz"};list.Add(新菜单{MenuText="abc",RoleName="Admin",ActionName="xyz"};list.Add(新菜单{MenuText="abc1",RoleName="Admin1",ActionName="xyz1"};list.Add(新菜单{MenuText="abc1",RoleName="Admin1",ActionName="xyz1"};///columnName:-菜单类的名称(MenuText或RoleName或ActionName)publicIEnumerable>GroupMenu(stringcolumnName){//这里我想获取组菜单列表bythecolumnName}}如果您不使用数据库,可以使用反射:privatestaticobjectGetPropertyValue(objectobj,stringpropertyName){returnobj.GetType().GetProperty(propertyName).GetValue(obj,null);}使用:vargrouped=enumeration.GroupBy(x=>GetPropertyValue(x,columnName));这是一个非常原始的解决方案,更好的方法应该是使用DynamicLINQ:vargrouped=enumeration.GroupBy(columnName,selector);编辑DynamicLINQ可能需要一些解释,它不是一种技术、一个库或全新的s框架。它只是一对(2000LOC)辅助方法的方便名称,可让您编写此类查询。只需下载源代码(如果您没有安装VS示例)并在您的代码中使用它们。最简单的方法:if(columnName=="MextText"){returnlist.GroupBy(x=>x.MenuText);}if(columnName=="RoleName"){returnlist.GroupBy(x=>x.RoleName);}if(columnName=="ActionName"){returnlist.GroupBy(x=>x.ActionName);}返回list.GroupBy(x=>x.MenuText);您还可以使用表达式树。privatestaticExpression>GetColumnName(stringproperty){varmenu=Expression.Parameter(typeof(Menu),"menu");varmenuProperty=Expression.PropertyOrField(菜单,属性);varlambda=Expression.Lambda>(menuProperty,menu);返回拉姆达;}返回list.GroupBy(GetColumnName(columnName).Compile());这将生成一个lambda菜单=>菜单。但是,在类变得臃肿之前,没有太大区别。以下方法适用于LINQtoObjects以及LINQtoEF/NHibernate等。它创建一个对应于作为字符串传递的列/属性的表达式,并将该表达式传递给GroupBy:varbody=Expression.Property(参数,属性);返回Expression.Lambda>(body,parameter);}使用基于IQueryable的数据源:context.Menus.GroupBy(GetGroupKey(columnName));使用基于IEnumerable的数据来源:list.GroupBy(GetGroupKey(columnName).Compile());顺便说一句:您的方法的返回类型应该是IEnumerable>,因为IGrouping已经意味着每个键可以有多个菜单实例。我按照AdrianopublicstaticIEnumerable>GroupByMany(thisIEnumerableelements,paramsstring[]groupSelectors){varselectors=newList>(groupSelectors.Length);的建议用DynamicLinq做了这个selectors.AddRange(groupSelectors.Select(selector=>DynamicExpression.ParseLambda(typeof(TElement),typeof(object),selector)).Select(l=>(Func)l.Compile()));返回元素.GroupByMany(选择器.ToArray());}publicstaticIEnumerable>GroupByMany(thisIEnumerableelements,paramsFunc[]groupSelectors){if(groupSelectors.Length>0){Funcselector=groupSelectors.First();返回元素.GroupBy(选择器);}返回空值;您可以轻松地为任何模型实施解决方案,我只是将其作为通用解决方案。publicstaticExpression>GetColumnName(stringproperty){varmenu=Expression.Parameter(typeof(TElement),"groupCol");varmenuProperty=Expression.PropertyOrField(菜单,属性);varlambda=Expression.Lambda>(menuProperty,menu);返回拉姆达;}调用如下_unitOfWork.MenuRepository.Get().GroupBy(LinqExtensions.GetColumnName("MenuText").Compile());非常感谢你的帮助。以上就是C#学习教程:LINQ动态群分享的全部内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: