@Mark Powell'ın cevabını beğendim ama @ShuberFu'nun dediği gibi hata veriyor LINQ to Entities only supports casting EDM primitive or enumeration types
.
Çıkarma var propAsObject = Expression.Convert(property, typeof(object));
, int nesnesini örtük olarak kutuya koymayacağı için, tamsayı gibi değer türleri olan özelliklerle çalışmadı.
Kristofer Andersson ve Marc Gravell'in Fikirlerini Kullanarak Sorgulanabilir işlevi özellik adını kullanarak oluşturmanın bir yolunu buldum ve hala Entity Framework ile çalışmasını sağladım. Ayrıca isteğe bağlı bir IComparer parametresi de ekledim. Dikkat: IComparer parametresi Entity Framework ile çalışmaz ve Linq to Sql kullanılıyorsa dışarıda bırakılmalıdır.
Aşağıdakiler Entity Framework ve Linq to Sql ile çalışır:
query = query.OrderBy("ProductId");
Ve @ Simon Scheurer bu da işe yarıyor:
query = query.OrderBy("ProductCategory.CategoryId");
Ve Entity Framework veya Linq to Sql kullanmıyorsanız, bu çalışır:
query = query.OrderBy("ProductCategory", comparer);
İşte kod:
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)
)
);
}
}