ผมชอบคำตอบจาก@ Mark Powellแต่เป็น@ShuberFuLINQ to Entities only supports casting EDM primitive or enumeration types
กล่าวว่ามันจะช่วยให้ข้อผิดพลาด
การนำออกใช้var propAsObject = Expression.Convert(property, typeof(object));
ไม่ได้กับคุณสมบัติที่เป็นประเภทค่าเช่นจำนวนเต็มเนื่องจากจะไม่ใส่กล่อง int to object โดยปริยาย
การใช้ไอเดียจากKristofer AnderssonและMarc Gravellฉันพบวิธีสร้างฟังก์ชัน Queryable โดยใช้ชื่อคุณสมบัติและยังใช้งานได้กับ Entity Framework ฉันยังรวมพารามิเตอร์ IComparer ที่เป็นทางเลือก ข้อควรระวัง:พารามิเตอร์ IComparer ใช้ไม่ได้กับ Entity Framework และควรละไว้หากใช้ Linq เป็น Sql
สิ่งต่อไปนี้ใช้ได้กับ Entity Framework และ Linq ถึง Sql:
query = query.OrderBy("ProductId");
และ@Simon Scheurerสิ่งนี้ยังใช้งานได้:
query = query.OrderBy("ProductCategory.CategoryId");
และถ้าคุณไม่ได้ใช้ Entity Framework หรือ Linq to Sql สิ่งนี้จะใช้ได้:
query = query.OrderBy("ProductCategory", comparer);
นี่คือรหัส:
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)
)
);
}
}