使用类属性对列表进行分组和拆分
本文关键字:拆分 列表 属性 | 更新日期: 2023-09-27 18:25:59
我有以下代码,我真的很想将其生成,这样我就不必根据字段调用相同的LINQ语句。
有没有一种方法可以将这个switch语句移到ItemViewModel中,并调用以检索一个通用属性来根据其字符串名称执行分组?
private List<List<ItemViewModel>> SplitItemList(List<List<ItemViewModel>> ItemLists,
string groupingField)
{
var newItemLists = new List<List<ItemViewModel>>();
foreach (var itemList in ItemLists)
{
var newList = new List<List<ItemViewModel>>();
switch (groupingField)
{
case "problem_description":
newList = itemList
.GroupBy(a => a.ProblemDescription)
.Select(x => x.ToList())
.ToList();
break;
case "sw_code":
newList = itemList
.GroupBy(a => a.SoftwareCode)
.Select(x => x.ToList())
.ToList();
break;
case "hw_code":
newList = itemList
.GroupBy(a => a.HardwareCode)
.Select(x => x.ToList())
.ToList();
break;
case "etc":
break;
default:
break;
}
newItemLists.AddRange(newList);
}
return newItemLists;
}
在循环中,尝试动态创建lambda:
public static Func<TIn, TOut> CreateGetter<TIn, TOut>(string propertyName)
{
var input = Expression.Parameter(typeof(TIn));
var expression = Expression.Property(input, typeof(TIn).GetProperty(propertyName));
return Expression.Lambda<Func<TIn, TOut>>(expression, input).Compile();
}
这样说吧:
var list = new List<Tuple<string, string>>();
var getter = DynamicLinq.CreateGetter<Tuple<string, string>, string>("Item1");
var query = list.GroupBy(getter).Select(x => x.ToList());
不过,请确保"groupingField"是属性的确切名称,否则这将不起作用。
编辑时间:根据您的评论,我给出了一个与您的场景相关的自定义属性使用示例:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class FriendlyNameAttribute : Attribute
{
public string FriendlyName { get; set; }
public FriendlyNameAttribute(string friendlyName)
{
FriendlyName = friendlyName;
}
}
public class ItemViewModel
{
private static readonly IDictionary<string, string> PropertyMap;
static ItemViewModel()
{
PropertyMap = new Dictionary<string, string>();
var myType = typeof (ItemViewModel);
foreach (var propertyInfo in myType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
{
if (propertyInfo.GetGetMethod() != null)
{
var attr = propertyInfo.GetCustomAttribute<FriendlyNameAttribute>();
if (attr == null)
continue;
PropertyMap.Add(attr.FriendlyName, propertyInfo.Name);
}
}
}
public static string GetPropertyMap(string groupingField)
{
string propName;
PropertyMap.TryGetValue(groupingField, out propName);
return propName; //will return null in case map not found.
}
[FriendlyName("problem_description")]
public string ProblemDescription { get; set; }
public string OtherProperty { get; set; } // will not be in map
}
这样使用:
var x = ItemViewModel.GetPropertyMap("problem_description");