通过代码中的第一个EF存储库传递动态表达式

Abd*_*Ali 12 c# linq entity-framework

我们编写了一个Generic函数,首先从存储库模式中获取EF代码中的记录.休息似乎没问题,但是当将Integer传递给动态订单时,它说Cannot cast System.Int32 to System.Object

表达式如下:

Expression<Func<HeadOffice, object>> orderByFunc = o =>  o.Id;

if (options.sort == "Id")
{
         // this is an Integer
    orderByFunc = o => o.Id;
}
if (options.sort =="Name")
{
   // string
    orderByFunc = o => o.Name;
}
if (options.sort == "Code")
{
    orderByFunc = o => o.Code;
}
Run Code Online (Sandbox Code Playgroud)

通用方法如下:

public virtual IEnumerable<TEntity> GetSorted<TSortedBy>(
    Expression<Func<TEntity, object>> order,
    int skip, int take, 
    params Expression<Func<TEntity, object>>[] includes)
{
    IQueryable<TEntity> query = dbSet;

    foreach (var include in includes)
    {
        query = dbSet.Include(include);
    }

    IEnumerable<TEntity> data = query.OrderBy(order).Skip(skip).Take(take).ToList();

    return data;
}
Run Code Online (Sandbox Code Playgroud)

如果我们转换Expression<Func<TEntity, object>>Expression<Func<TEntity, int>>那么它似乎与整数工作正常,但因此没有字符串

任何帮助赞赏.

oct*_*ccl 6

也许如果您为此更改该参数的类型Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy,它可能会让您的生活更轻松:

public virtual IEnumerable<TEntity> GetSorted(Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy,...)
{
    IQueryable<TEntity> query = dbSet;
    //...
    if (orderBy != null)
    {
        query = orderBy(query);
    }
    //...
}
Run Code Online (Sandbox Code Playgroud)

这样你可以传递Func这样的:

Func<IQueryable<HeadOffice>, IOrderedQueryable<HeadOffice>> orderBy=null;
if (options.sort == "Id")
{
   orderBy= query=>query.OrderBy(o => o.Id);
}
//...
Run Code Online (Sandbox Code Playgroud)

更新

我现在注意到的另一件事是你没有使用TSortedBy泛型参数,所以,你也可以这样做:

public virtual IEnumerable<TEntity> GetSorted<TSortedBy>(Expression<Func<TEntity, TSortedBy>> order,
                                                         int skip, int take, 
                                                         params Expression<Func<TEntity, object>>[] includes)
{
}
Run Code Online (Sandbox Code Playgroud)

但无论如何,我认为最好使用第一个选项并删除该泛型参数.

  • 这正是我们在自己的通用存储库中处理这个问题的方法.这种方式也允许您对降序进行排序. (2认同)

Yac*_*sad 2

一种解决方案是有两个重载方法,其中一个需要

Expression<Func<TEntity, int>>
Run Code Online (Sandbox Code Playgroud)

一个需要

Expression<Func<TEntity, string>>
Run Code Online (Sandbox Code Playgroud)

为了最大限度地减少代码重复,请将公共代码(例如查询初始化语句和 for 循环)提取到共享方法中,然后让两个方法调用此共享方法,然后对结果调用 OrderBy。