【问题标题】:Linq query by parametersLinq 参数查询
【发布时间】:2016-03-09 11:22:40
【问题描述】:

我正在尝试实现一种使用 NHibernate 和 Linq 进行查询的新方法。方法是:

public object Query(Expression<Func<T, bool>> whereExpression, Expression<Func<T, object>> groupExpressionKeySelector, Expression<Func<object, IEnumerable<T>, object>> resultSelector)
{
        var results = Session.Query<T>().Where(whereExpression).GroupBy(groupExpressionKeySelector, resultSelector).ToList();
        return results;
}

电话是这样的:

    Expression<Func<Serial, bool>> whereExpression = serial => serial.Status == Status.Ok;
Expression<Func<Serial, object>> groupExpressionKeySelector = serial => serial.Type.Code;
Expression<Func<object, IEnumerable<Serial>, object>> groupExpressionResultSelector = (key, q) => new { Id = key, Quantity = q.Count() };

var results = this.SerialRepository.Query(whereExpression, groupExpressionKeySelector, groupExpressionResultSelector);

问题是这句话引发了异常 System.Reflection.TargetInvocationException' with:

{"Ningún método genérico 'GroupBy' para el tipo 'System.Linq.Enumerable' es compatible con los argumentos normales y de tipo proporcionados. No se deben proporcionar argumentos de tipo si el método no es genérico."}

似乎不需要输入类型的参数...你知道发生了什么吗?没有参数 resultSelector 一切正常..

【问题讨论】:

  • 在我看来,您尝试将 Linq 可查询 API 复制到您自己的中。你真的需要那个吗?为什么不直接使用来自调用者的IQueryable 对象?因为是业务逻辑?如果是,它不应该能够提供过滤/分组/投影逻辑,这确实属于存储库,而不是业务逻辑。
  • 并且您应该提供异常消息的翻译版本。 (如果您愿意,可以使用“近似翻译”之类的免责声明。)

标签: c# database linq nhibernate group-by


【解决方案1】:

正如my comment 所述,我怀疑你的机箱设计得很好。

无论如何,我怀疑问题在于object 键入的键太宽泛,需要更具体。也许您当前的输入会阻止编译器选择正确的GroupBy 重载。为您的方法添加更多通用参数。

public object Query<TKey>(Expression<Func<T, bool>> whereExpression,
    Expression<Func<T, TKey>> groupExpressionKeySelector,
    Expression<Func<TKey, IEnumerable<T>, object>> resultSelector)
{
        var results = Session.Query<T>()
            .Where(whereExpression)
            .GroupBy(groupExpressionKeySelector, resultSelector)
            .ToList();
        return results;
}

那么,假设serial.Type.Code是string:

Expression<Func<Serial, bool>> whereExpression =
    serial => serial.Status == Status.Ok;
Expression<Func<Serial, string>> groupExpressionKeySelector =
    serial => serial.Type.Code;
Expression<Func<string, IEnumerable<Serial>, object>> groupExpressionResultSelector = 
    (key, q) => new { Id = key, Quantity = q.Count() };

var results = this.SerialRepository.Query(whereExpression,
    groupExpressionKeySelector, groupExpressionResultSelector);

但这可能还不够。您可能需要完全通用。由于匿名输入,需要直接提供resultSelector:

public List<TResult> Query<TKey, TResult>(Expression<Func<T, bool>> whereExpression,
    Expression<Func<T, TKey>> groupExpressionKeySelector,
    Expression<Func<TKey, IEnumerable<T>, TResult>> resultSelector)
{
        var results = Session.Query<T>()
            .Where(whereExpression)
            .GroupBy(groupExpressionKeySelector, resultSelector)
            .ToList();
        return results;
}

那么,仍然假设serial.Type.Code是string:

Expression<Func<Serial, bool>> whereExpression =
    serial => serial.Status == Status.Ok;
Expression<Func<Serial, string>> groupExpressionKeySelector =
    serial => serial.Type.Code;

var results = this.SerialRepository.Query(whereExpression,
    groupExpressionKeySelector, 
    (key, q) => new { Id = key, Quantity = q.Count() });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-07
    • 2014-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多