Saya menyukai jawaban dari @Mark Powell , tetapi seperti yang dikatakan @ShuberFu , itu memberikan kesalahan LINQ to Entities only supports casting EDM primitive or enumeration types
.
Penghapusan var propAsObject = Expression.Convert(property, typeof(object));
tidak berfungsi dengan properti yang merupakan tipe nilai, seperti integer, karena tidak secara implisit mengotakkan int ke objek.
Menggunakan Ide dari Kristofer Andersson dan Marc Gravell Saya menemukan cara untuk membangun fungsi Querable menggunakan nama properti dan masih berfungsi dengan Entity Framework. Saya juga menyertakan parameter IComparer opsional. Perhatian: Parameter IComparer tidak bekerja dengan Entity Framework dan harus ditinggalkan jika menggunakan Linq ke Sql.
Berikut ini bekerja dengan Entity Framework dan Linq to Sql:
query = query.OrderBy("ProductId");
Dan @Simon Scheurer ini juga berfungsi:
query = query.OrderBy("ProductCategory.CategoryId");
Dan jika Anda tidak menggunakan Entity Framework atau Linq ke Sql, ini berfungsi:
query = query.OrderBy("ProductCategory", comparer);
Ini kodenya:
public static class IQueryableExtensions
{
public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> query, string propertyName, IComparer<object> comparer = null)
{
return CallOrderedQueryable(query, "OrderBy", propertyName, comparer);
}
public static IOrderedQueryable<T> OrderByDescending<T>(this IQueryable<T> query, string propertyName, IComparer<object> comparer = null)
{
return CallOrderedQueryable(query, "OrderByDescending", propertyName, comparer);
}
public static IOrderedQueryable<T> ThenBy<T>(this IOrderedQueryable<T> query, string propertyName, IComparer<object> comparer = null)
{
return CallOrderedQueryable(query, "ThenBy", propertyName, comparer);
}
public static IOrderedQueryable<T> ThenByDescending<T>(this IOrderedQueryable<T> query, string propertyName, IComparer<object> comparer = null)
{
return CallOrderedQueryable(query, "ThenByDescending", propertyName, comparer);
}
public static IOrderedQueryable<T> CallOrderedQueryable<T>(this IQueryable<T> query, string methodName, string propertyName,
IComparer<object> comparer = null)
{
var param = Expression.Parameter(typeof(T), "x");
var body = propertyName.Split('.').Aggregate<string, Expression>(param, Expression.PropertyOrField);
return comparer != null
? (IOrderedQueryable<T>)query.Provider.CreateQuery(
Expression.Call(
typeof(Queryable),
methodName,
new[] { typeof(T), body.Type },
query.Expression,
Expression.Lambda(body, param),
Expression.Constant(comparer)
)
)
: (IOrderedQueryable<T>)query.Provider.CreateQuery(
Expression.Call(
typeof(Queryable),
methodName,
new[] { typeof(T), body.Type },
query.Expression,
Expression.Lambda(body, param)
)
);
}
}