【问题标题】:Ordering by Index of property in Anonymous Type Declaration在匿名类型声明中按属性索引排序
【发布时间】:2015-05-24 04:04:47
【问题描述】:

我有一个复杂的问题,没有涉及太多细节。我只是想知道这是否可能。

我有一个 Ordered Linq 查询,它获取数据子集并将其推送到 DataTable 中。

var FormattedDataSet = DataSet.Select(t => new
{
    ItemNumber = t.ExtTitleID,
    Name = "<a href='/Title/Preview/" + t.ID + "'>" + t.TitleFullName + "</a>",
    Master_Edited = t.MediaDetails.FirstOrDefault().Datecaptured
}).ToList();

Int 是否可以根据匿名类型声明的索引来排序?

0 => ItemNumber
1 => Name
2 => MasterEdited

我需要能够在不明确声明要排序的列名的情况下执行此操作,因此这通常适用于任何匿名类型。

【问题讨论】:

标签: c# linq


【解决方案1】:

是和不是。您不能直接执行此操作,并且匿名类型(或任何对象)的属性/字段不会被索引。因此,您不能使用索引来访问这些属性。

话虽如此,您可以使用反射来访问不带名称的数据。

var FormattedDataSet = /*linq query to create list of anon types*/

//we only need to analyze one of them since all items in the list should be of the same type
Type t = formattedDataSet[0].GetType(); 
PropertyInfo[] pi = t.GetProperties();

//get value of "property one" of the first anon object in your list
object data = pi[0].GetValue(FormattedDataSet[0]);

上面的代码创建了一个属性数组,您可以在其上使用索引,尽管您不知道这些属性实际上是什么。然后,您可以遍历 PropertyInfo 对象数组并调用 propInfo.GetValue(anonObject); 以返回匿名对象中该属性中存储的值。

如果您想从PropertyInfo 对象中获取属性的名称,您可以调用propInfo.Name。

【讨论】:

  • 属性有别名如果我总是按字母顺序订购匿名类型,是否可以检查匿名类型别名
  • 我编辑了我的帖子,向您展示如何从 PropertyInfo 对象中获取名称,但是如果您已经知道它们,为什么还要为此烦恼,因为您可以调用 anonObject.Alias,因为它们自动成为属性。 (除非我不明白你所说的别名是什么意思)
  • 完美我仍然需要属性名称来调用 OrderBy 使用动态 linq
  • 所以只是想知道,属性数组是否按照为什么在匿名类型中使用 delcare 的顺序初始化值?
  • @Space 我相信它们是按照它们在数组中声明的顺序排列的,但是您需要对其进行测试,因为 MSDN 上 Type 类的文档没有说明元素是如何调用GetProperties()时排序
【解决方案2】:

我希望这还不算太晚,但我有一些工作代码给你。我之前在一个项目中使用过它,它没有引起任何明显的问题。

public static IOrderedQueryable<T> OrderByPropertyDeclarionIndex<T>(this IQueryable<T> source, int propertyIndex, bool isDescending = false)
{
    string OrderByText = isDescending ? "OrderByDescending" : "OrderBy";
    return ApplyOrder(source, propertyIndex, OrderByText);
}


private static IOrderedQueryable<T> ApplyOrder<T>(IQueryable<T> source, int property, string methodName)
{

    var type = typeof(T);
    var arg = Expression.Parameter(type, "x");
    Expression expr = arg;

    var propertyinfos = type.GetProperties();


    var pi = propertyinfos[property];



    expr = Expression.Property(expr, pi);
    type = pi.PropertyType;

    var delegateType = typeof(Func<,>).MakeGenericType(typeof(T), type);
    var lambda = Expression.Lambda(delegateType, expr, arg);

    var result = typeof(Queryable).GetMethods().Single(
            method => method.Name == methodName
                    && method.IsGenericMethodDefinition
                    && method.GetGenericArguments().Length == 2
                    && method.GetParameters().Length == 2)
            .MakeGenericMethod(typeof(T), type)
            .Invoke(null, new object[] { source, lambda });
    return (IOrderedQueryable<T>)result;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 2015-03-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多