没有通用方法“ ThenBy” [英] No generic method 'ThenBy'
问题描述
我正在尝试添加 ThenById()
方法,该方法将在调用 OrderBy()
之后启动在 IOrderedQueryable
I am trying to add the ThenById()
method which will be launched after a call to OrderBy()
on IOrderedQueryable
:
public static IOrderedQueryable<TEntity> ThenById<TEntity>(this IQueryable<TEntity> source)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
var command = "ThenBy";
var thenByProperty = "Id";
var type = typeof(TEntity);
if (type.GetProperty(thenByProperty) == null)
{
throw new MissingFieldException(nameof(thenByProperty));
}
var param = Expression.Parameter(type, "p");
var property = type.GetProperty(thenByProperty, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
var propertyAccess = Expression.MakeMemberAccess(param, property);
var orderByExpression = Expression.Lambda(propertyAccess, param);
var resultExpression = Expression.Call(
typeof(IOrderedQueryable),
command,
new Type[] { type, property.PropertyType },
source.Expression,
Expression.Quote(orderByExpression));
return (IOrderedQueryable<TEntity>)source.Provider.CreateQuery<TEntity>(resultExpression);
}
我收到以下错误消息:
类型'System.Linq.IOrderedQueryable'上的通用方法'ThenBy'与提供的类型实参和实参不兼容。如果方法是非泛型的,则不应该提供任何类型参数。
No generic method 'ThenBy' on type 'System.Linq.IOrderedQueryable' is compatible with the supplied type arguments and arguments. No type arguments should be provided if the method is non-generic.
推荐答案
ThenBy
扩展方法在 System.Linq.Queryable
类中,而不在 IOrderedQueryable $ c中$ c>。您只需要在代码中替换掉它即可。
The ThenBy
extension method is in the System.Linq.Queryable
class, not in IOrderedQueryable
. You simply need to replace that in your code:
public static IOrderedQueryable<TEntity> ThenById<TEntity>(
this IOrderedQueryable<TEntity> source)
{
//snip
var resultExpression = Expression.Call(
typeof(System.Linq.Queryable),
command,
new Type[] { type, property.PropertyType },
source.Expression,
Expression.Quote(orderByExpression));
return (IOrderedQueryable<TEntity>)source.Provider.CreateQuery<TEntity>(resultExpression);
}
请注意,该方法应扩展 IOrderedQueryable
,而不仅仅是 IQueryable
。
Note that the method should be extending IOrderedQueryable
, not just IQueryable
.
但是,如果 TEntity
没有 Id
属性。我的偏好是为所有具有 Id
属性的实体提供一个接口,并在此使用通用约束。这样,您可以完全避免使用表达式,并获得编译时的安全性。例如:
However, this will fail at runtime if TEntity
doesn't have an Id
property. My preference would be to give all entities with the Id
property an interface and use a generic constraint here. That way you avoid expressions completely and get compile time safety. For example:
public interface IHasId
{
int Id { get; set; }
}
public class SomeEntity : IHasId
{
public int Id { get; set; }
public string Name { get; set; }
//etc
}
这简化了扩展方法:
public static IOrderedQueryable<TEntity> ThenById<TEntity>(
this IOrderedQueryable<TEntity> source)
where TEntity : IHasId
{
return source.ThenBy(e => e.Id);
}
这篇关于没有通用方法“ ThenBy”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!