我有一个名为Employee
的类(这只是其中的一部分):
public class Employee
{
public int ID { get; set; }
public string Place { get; set; }
[IncludeinReport]
public string BusinessVertical { get; set; }
[IncludeinReport]
public string Region { get; set; }
public string Country { get; set; }
[IncludeinReport]
public string BusinessUnit { get; set; }
}
我想使用Linq只选择具有IncludeinReport
属性的属性。下面是我现在使用的linq,我要做的只是手动选择具有以下属性的属性:
var report = from c in Employee
orderby c.Region, c.BusinessUnit
select new
{
c.BusinessVertical,
c.Region,
c.BusinessUnit,
}
但是我希望能够做这样的事情:
var report = from c in Employee
orderby c.Region, c.BusinessUnit
select c.members.hasattribute(IncludeinReport)
答案 0 :(得分:0)
不确定这是否是最好的方法,但是您可以执行以下操作。
对象
public class Employee
{
public int ID { get; set; }
public string Place { get; set; }
[IncludeinReport]
public string BusinessVertical { get; set; }
[IncludeinReport]
public string Region { get; set; }
public string Country { get; set; }
[IncludeinReport]
public string BusinessUnit { get; set; }
}
public class IncludeinReport:Attribute
{
}
样本数据
var list = new List<Employee>
{
new Employee{ID = 1, Region = "Europe", BusinessUnit="Software", BusinessVertical = "Sample1"},
new Employee{ID = 1, Region = "Asia", BusinessUnit="Software", BusinessVertical = "Sample1"},
new Employee{ID = 1, Region = "Asia", BusinessUnit="Hardware", BusinessVertical = "Sample1"},
new Employee{ID = 1, Region = "Europe", BusinessUnit="Software", BusinessVertical = "Sample1"},
new Employee{ID = 1, Region = "Asia", BusinessUnit="Telecom", BusinessVertical = "Sample1"},
new Employee{ID = 1, Region = "Europe", BusinessUnit="Software", BusinessVertical = "Sample1"},
};
对于以上内容,您可以查询如下。您需要获取具有必需属性的属性。此属性列表用于查询数据。最后,您可以使用ExpandoObject创建所需的类型。
var properties = typeof(Employee).GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(IncludeinReport))).Select(v=>v);
var intermediate = list.OrderBy(c => c.Region).ThenBy(x=>x.BusinessUnit).SelectMany((x,index)=> properties.Select(v=> new {GroupId = index, Dict = new KeyValuePair<string,object>(v.Name, v.GetValue(x))})) ;
var resultList = new List<ExpandoObject>();
foreach(var item in intermediate.GroupBy(x=>x.GroupId))
{
resultList.Add(CreateObject(item.ToList().Select(x=>x.Dict)));
}
其中CreateObject定义为
ExpandoObject CreateObject(IEnumerable<KeyValuePair<string,object>> kvps)
{
dynamic returnValue = new ExpandoObject();
var dict = returnValue as IDictionary<string, object>;
foreach (var kvp in kvps)
{
dict.Add(kvp.Key, kvp.Value);
}
return returnValue;
}
输出
更新
您可以对CreateObject使用扩展方法,这会使它易于阅读。
public static class Extensions
{
public static ExpandoObject CreateObject(this IEnumerable<KeyValuePair<string,object>> source)
{
dynamic returnValue = new ExpandoObject();
var dict = returnValue as IDictionary<string, object>;
foreach (var kvp in source)
{
dict.Add(kvp.Key, kvp.Value);
}
return returnValue;
}
}
此后,查询变为。
var properties = typeof(Employee).GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(IncludeinReport))).Select(v=>v);
var intermediate = list.OrderBy(c => c.Region).ThenBy(x=>x.BusinessUnit).SelectMany((x,index)=> properties.Select(v=> new {GroupId = index, Dict = new KeyValuePair<string,object>(v.Name, v.GetValue(x))})) ;
var resultList = intermediate.GroupBy(x=>x.GroupId).Select(x=>x.ToList().Select(c=>c.Dict).CreateObject());