我有以下代码,我真的想要通用,所以我不必调用依赖于该字段的相同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;
}
答案 0 :(得分:0)
在循环中,尝试动态创建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());
确保&#34; groupingField&#34;是该物业的确切名称,否则这不会起作用。
EDITED :: 根据您的评论,我将举例说明与您的方案相关的自定义属性用法:
[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");