Linq使用属性名称相等

时间:2018-04-11 16:08:58

标签: c# linq

我有一个以我从用户数据源读入的方式构建的类:

Item
Warehouse
Customer
Forecast_4_2018
Forecast_5_2018

等等 - 我正在对这些数据进行一些计算,并希望动态选择哪个"预测"当月使用的财产。

int year, int month
PropertyInfo[] properties = typeof(CombinedForecast).GetProperties();
PropertyInfo useThisForecast = null;
foreach (PropertyInfo property in properties)
{
    if(property.Name.ContainsAll(year.ToString(), month.ToString()))
    {
        useThisForecast = property;                   
    }       
}

所以在这种情况下useThisForecast == Forecast_4_2018

我有一个LINQ查询来对数据进行分组并对数量求和,但我想指定属性与属性名称相加。

var results = from a in CombinedForecast
    group a by new
    {
        a.ItemNumber,
        a.ShipFromNumber,
        a.ShipToNumber
    } into grouping
    select new SummedOrders
    {
        SummedQuantity = grouping.Sum(x => x.Forecast_4_2018.Value /*x.GetType().Name.Equals(useThisForecast.Name).Value */ ),
        Item = grouping.Key.ItemNumber,
        Warehouse = grouping.Key.ShipFromNumber.ParseInt(),
        CustomerNumber = grouping.Key.ShipToNumber
    };

return results.ToList();

在下面的代码中,我尝试使用属性的名称,而不是设置它,但我无法正确使用语法。

 SummedQuantity = grouping.Sum(x => x.Forecast_4_2018.Value /*x.GetType().Name.Equals(useThisForecast.Name).Value */

1 个答案:

答案 0 :(得分:2)

您需要使用PropertyInfo.GetValue方法从正确类型的对象中检索相应的属性值:

SummedQuantity = grouping.Sum(x => (dynamic)useThisForecast.GetValue(x));

请注意,GetValue会返回您可能需要投放的object - 我作弊并使用dynamic,因为我不知道属性的类型。

此外,如果您可能正在处理字段或属性,MemberInfo上的某些扩展方法可能会有所帮助:

public static object GetValue(this MemberInfo member, object srcObject) {
    switch (member) {
        case FieldInfo mfi:
            return mfi.GetValue(srcObject);
        case PropertyInfo mpi:
            return mpi.GetValue(srcObject);
        default:
            throw new ArgumentException("MemberInfo must be of type FieldInfo or PropertyInfo", nameof(member));
    }
}

public static Type GetMemberType(this MemberInfo member) {
    switch (member) {
        case FieldInfo mfi:
            return mfi.FieldType;
        case PropertyInfo mpi:
            return mpi.PropertyType;
        case EventInfo mei:
            return mei.EventHandlerType;
        default:
            throw new ArgumentException("MemberInfo must be if type FieldInfo, PropertyInfo or EventInfo", nameof(member));
    }
}