C# Linq OrderBy 反射与 .分隔字符串
C# Linq OrderBy Reflection with . deliminated string
我需要使用定界字符串来排序。 EG "Product.Reference".
我似乎遇到了问题,因为结果的排序方式与调用方法之前的排序方式相同。
例如,我的 xUnit 测试显示了我的问题。
断言显示顺序仍然相同。
编辑:
需要明确的是,我不是在测试 Order by,而是在测试 PathToProperty 方法。
此测试仅用于演示目的。
正如您从测试中看到的那样,我在方法中使用反射 private static object PathToProperty(object t, string path)
所以我假设我在那里做错了什么?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Xunit;
namespace Pip17PFinanceApi.Tests.Workers
{
public class InputViewModel
{
public List<OrderViewModel> OrderViewModels { get; set; }
}
public class OrderViewModel
{
public Product Product { get; set; }
public decimal Price { get; set; }
}
public class Product
{
public string Description { get; set; }
public string Reference { get; set; }
}
public class OrderByWithReflection
{
[Fact]
public void OrderByTest()
{
//Arrrange
var model = new InputViewModel
{
OrderViewModels = new List<OrderViewModel>
{
new OrderViewModel{
Product = new Product
{
Reference = "02"
}
},
new OrderViewModel{
Product = new Product
{
Reference = "03"
}
},
new OrderViewModel{
Product = new Product
{
Reference = "01"
}
},
new OrderViewModel{
Product = new Product
{
Reference = "04"
}
},
}
};
//Act
var query = model.OrderViewModels.OrderBy(t => PathToProperty(t, "Product.Reference"));
var result = query.ToList();
//Assert
Assert.Equal("01", result[0].Product.Reference);
Assert.Equal("02", result[1].Product.Reference);
Assert.Equal("03", result[2].Product.Reference);
Assert.Equal("04", result[3].Product.Reference);
}
private static object PathToProperty(object t, string path)
{
Type currentType = t.GetType();
foreach (string propertyName in path.Split('.'))
{
PropertyInfo property = currentType.GetProperty(propertyName);
t = property;
currentType = property.PropertyType;
}
return t;
}
}
}
您的 PathToProperty
不正确。考虑一下它的 return 值 - 上次通过时,您设置了 t = property
然后 return t
。但是 property
是 PropertyInfo
,所以你只是比较 OrderBy
.
中的相同对象
我有一个类似的扩展方法:
public static object GetPropertyPathValue(this object curObject, string propsPath) {
foreach (var propName in propsPath.Split('.'))
curObject = curObject.GetType().GetProperty(propName).GetValue(curObject);
return curObject;
}
如果用来代替您的 PathToProperty
方法,OrderBy
将起作用。
var query = model.OrderViewModels.OrderBy(t => t.GetPropertyPathValue("Product.Reference"));
您可以将方法更新为:
private static object PathToProperty(object curObject, string path) {
foreach (string propertyName in path.Split('.')) {
var property = curObject.GetType().GetProperty(propertyName);
curObject = property.GetValue(curObject);
}
return curObject;
}
同样的结果。
PS 实际上,使用其他一些扩展方法和 LINQ,我的常规方法处理属性或字段:
public static object GetPathValue(this object curObject, string memberPath)
=> memberPath.Split('.').Aggregate(curObject, (curObject, memberName) => curObject.GetType().GetPropertyOrField(memberName).GetValue(curObject));
我需要使用定界字符串来排序。 EG "Product.Reference".
我似乎遇到了问题,因为结果的排序方式与调用方法之前的排序方式相同。
例如,我的 xUnit 测试显示了我的问题。 断言显示顺序仍然相同。
编辑: 需要明确的是,我不是在测试 Order by,而是在测试 PathToProperty 方法。 此测试仅用于演示目的。
正如您从测试中看到的那样,我在方法中使用反射 private static object PathToProperty(object t, string path)
所以我假设我在那里做错了什么?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Xunit;
namespace Pip17PFinanceApi.Tests.Workers
{
public class InputViewModel
{
public List<OrderViewModel> OrderViewModels { get; set; }
}
public class OrderViewModel
{
public Product Product { get; set; }
public decimal Price { get; set; }
}
public class Product
{
public string Description { get; set; }
public string Reference { get; set; }
}
public class OrderByWithReflection
{
[Fact]
public void OrderByTest()
{
//Arrrange
var model = new InputViewModel
{
OrderViewModels = new List<OrderViewModel>
{
new OrderViewModel{
Product = new Product
{
Reference = "02"
}
},
new OrderViewModel{
Product = new Product
{
Reference = "03"
}
},
new OrderViewModel{
Product = new Product
{
Reference = "01"
}
},
new OrderViewModel{
Product = new Product
{
Reference = "04"
}
},
}
};
//Act
var query = model.OrderViewModels.OrderBy(t => PathToProperty(t, "Product.Reference"));
var result = query.ToList();
//Assert
Assert.Equal("01", result[0].Product.Reference);
Assert.Equal("02", result[1].Product.Reference);
Assert.Equal("03", result[2].Product.Reference);
Assert.Equal("04", result[3].Product.Reference);
}
private static object PathToProperty(object t, string path)
{
Type currentType = t.GetType();
foreach (string propertyName in path.Split('.'))
{
PropertyInfo property = currentType.GetProperty(propertyName);
t = property;
currentType = property.PropertyType;
}
return t;
}
}
}
您的 PathToProperty
不正确。考虑一下它的 return 值 - 上次通过时,您设置了 t = property
然后 return t
。但是 property
是 PropertyInfo
,所以你只是比较 OrderBy
.
我有一个类似的扩展方法:
public static object GetPropertyPathValue(this object curObject, string propsPath) {
foreach (var propName in propsPath.Split('.'))
curObject = curObject.GetType().GetProperty(propName).GetValue(curObject);
return curObject;
}
如果用来代替您的 PathToProperty
方法,OrderBy
将起作用。
var query = model.OrderViewModels.OrderBy(t => t.GetPropertyPathValue("Product.Reference"));
您可以将方法更新为:
private static object PathToProperty(object curObject, string path) {
foreach (string propertyName in path.Split('.')) {
var property = curObject.GetType().GetProperty(propertyName);
curObject = property.GetValue(curObject);
}
return curObject;
}
同样的结果。
PS 实际上,使用其他一些扩展方法和 LINQ,我的常规方法处理属性或字段:
public static object GetPathValue(this object curObject, string memberPath)
=> memberPath.Split('.').Aggregate(curObject, (curObject, memberName) => curObject.GetType().GetPropertyOrField(memberName).GetValue(curObject));