原文:http://www.codeproject.com/Tips/817372/Building-OrderBy-Lambda-Expression-from-Property-N
Fork地址:https://dotnetfiddle.net/sEmFzq
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
public class Phone
{
public double Price { get; set; }
public string Brand { get; set; }
}
public class Db
{
public static IQueryable<Phone> Phones
{
get
{
return new List<Phone>()
{
new Phone(){ Price = 2, Brand = "A"},
new Phone(){ Price = 1, Brand = "B"}
}.AsQueryable();
}
}
}
public static class Utility
{
//makes expression for specific prop
public static Expression<Func<TSource, object>> GetExpression<TSource>(string propertyName)
{
var param = Expression.Parameter(typeof(TSource), "x");
Expression conversion = Expression.Convert(Expression.Property(param, propertyName), typeof(object)); //important to use the Expression.Convert
return Expression.Lambda<Func<TSource, object>>(conversion, param);
}
//makes deleget for specific prop
public static Func<TSource, object> GetFunc<TSource>(string propertyName)
{
return GetExpression<TSource>(propertyName).Compile(); //only need to compiled expression
}
//OrderBy overload
public static IOrderedEnumerable<TSource> OrderBy<TSource>(this IEnumerable<TSource> source, string propertyName)
{
return source.OrderBy(GetFunc<TSource>(propertyName));
}
//OrderBy overload
public static IOrderedQueryable<TSource> OrderBy<TSource>(this IQueryable<TSource> source, string propertyName)
{
return source.OrderBy(GetExpression<TSource>(propertyName));
}
}
public class Program
{
public static void Dump(IEnumerable<Phone> phones, string mesg)
{
Console.WriteLine("\n" + mesg);
foreach (var item in phones)
{
Console.WriteLine(String.Format("Brand = {0}, Price = {1}", item.Brand, item.Price));
}
}
public static void Main(string[] args)
{
List<Phone> orderedByPrice = null;
List<Phone> orderedByBrand = null;
/*When using lambda expression*/
orderedByPrice = Db.Phones.OrderBy(x => x.Price).ToList();
orderedByBrand = Db.Phones.OrderBy(x => x.Brand).ToList();
Dump(orderedByPrice, "lambda expression, Order By: Price");
Dump(orderedByBrand, "lambda expression, Order By: Brand");
/*When source is IQueryable*/
orderedByPrice = Db.Phones.OrderBy("Price").ToList();
orderedByBrand = Db.Phones.OrderBy("Brand").ToList();
Dump(orderedByPrice, "Source is IQueryable, Order By: Price");
Dump(orderedByBrand, "source is IQueryable, Order By: Brand");
/*When source is IEnumerable*/
orderedByPrice = Db.Phones.AsEnumerable().OrderBy("Price").ToList();
orderedByBrand = Db.Phones.AsEnumerable().OrderBy("Brand").ToList();
Dump(orderedByPrice, "Source is IEnumerable, Order By: Price");
Dump(orderedByBrand, "Source is IEnumerable, Order By: Brand");
}
}
输出:
lambda expression, Order By: Price
Brand = B, Price = 1
Brand = A, Price = 2
lambda expression, Order By: Brand
Brand = A, Price = 2
Brand = B, Price = 1
Source is IQueryable, Order By: Price
Brand = B, Price = 1
Brand = A, Price = 2
source is IQueryable, Order By: Brand
Brand = A, Price = 2
Brand = B, Price = 1
Source is IEnumerable, Order By: Price
Brand = B, Price = 1
Brand = A, Price = 2
Source is IEnumerable, Order By: Brand
Brand = A, Price = 2
Brand = B, Price = 1