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。但是 propertyPropertyInfo,所以你只是比较 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));