没有通用方法“ThenBy" [英] No generic method 'ThenBy'

查看:28
本文介绍了没有通用方法“ThenBy"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试添加 ThenById() 方法,该方法将在 IOrderedQueryable 上调用 OrderBy() 后启动:

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.你只需要在你的代码中替换它:

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
}

这简化了您的扩展方法:

Which simplifies your extension method:

public static IOrderedQueryable<TEntity> ThenById<TEntity>(
    this IOrderedQueryable<TEntity> source)
        where TEntity : IHasId
{
    return source.ThenBy(e => e.Id);
}

这篇关于没有通用方法“ThenBy"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆