Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在.net core中使用表达式进行动态分组_C#_Entity Framework_Linq_Extension Methods - Fatal编程技术网

C# 在.net core中使用表达式进行动态分组

C# 在.net core中使用表达式进行动态分组,c#,entity-framework,linq,extension-methods,C#,Entity Framework,Linq,Extension Methods,我写了一个扩展方法,它根据条件生成一个表达式,但是当条件为groupby时,结果是orderby!!! 我怎么了 以下是我的方法: public static IQueryable<T> NewWhere<T, U>(this IQueryable<T> source, string prop, U value, string condition) { MethodInfo method; Expression<Func<T, bo

我写了一个扩展方法,它根据条件生成一个表达式,但是当条件为groupby时,结果是orderby!!! 我怎么了

以下是我的方法:

  public static IQueryable<T> NewWhere<T, U>(this IQueryable<T> source, string prop, U value, string condition)
  {
  MethodInfo method;
  Expression<Func<T, bool>> lambda = null;
  Expression body = null;

  string groupSelector = null;
  var type = typeof(T);
  var parameter = Expression.Parameter(type, "p");
  var property = Expression.Property(parameter, prop);
  var constant = Expression.Constant(value, typeof(U));


  if (condition == "GreaterThan")
  body = Expression.GreaterThan(property, constant);
  else if (condition == "LessThan")
  body = Expression.LessThan(property, constant);
  else if (condition == "Equals")
  body = Expression.Equal(property, constant);

  //For implement sql like command we need them
  else if (condition == "StartsWith") {
  method = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
  body = Expression.Call(property, method, constant);
  }
  else if (condition == "EndsWith")
  {
  method = typeof(string).GetMethod("EndsWith", new[] { typeof(string) });
  body = Expression.Call(property, method, constant);
  }
  else if (condition == "Contains")
  {
  method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
  body = Expression.Call(property, method, constant);
  }
  //For implement sql like command we need them

  //group by only one field
  if (condition == "GroupBy")
  groupSelector = prop;

  else
  lambda = Expression.Lambda<Func<T, bool>>(body, new[] { parameter });

  //return the grouped by result or not grouped by
  if (groupSelector != null)
  {
  var selectorExp = Expression.Lambda<Func<T, U>>(property, new ParameterExpression[] { parameter });
  source = source.GroupBy(selectorExp).SelectMany(g => g);
  //source.GroupBy(e => e.GetType().GetProperty(groupSelector)).SelectMany(gr => gr);
  }
  else
  source = source.Where(lambda);

  return source;
  }

我不知道为什么会这样;博士:EntityFramework使用查询,因为它是获取所需内容的最有效方法

实体框架所做的是将LINQ查询转换为SQL。检查代码的这一行:

source = source.GroupBy(selectorExp).SelectMany(g => g);
您正在分组(可能是按年份),然后选择组中的所有项目。实际上,您并不是在请求分组结果集,而是希望所有组中的所有项都位于单个平面结果集中。如果EF首先请求组,然后请求组项目,则必须首先选择所有组:

SELECT [e].[Year]
FROM [org].[Data] AS [e]
GROUP BY [e].[Year]
然后,它必须在每个组的一个查询中获取组项:

这当然是非常低效的(尤其是因为您使用
SelectMany
)将列表展平,因此EF将只获取分组谓词排序的值,并在查询执行期间对它们进行分组(或者在本例中根本不对它们分组,因为您请求的是一个平面列表)。一旦执行了查询,EF就可以从结果集的顶部开始,并在每次遇到新年时启动一个新组


当您使用EF查询时,您必须接受无法控制SQL的事实。如果需要,请创建存储过程并从EF运行它们。

我遇到了这个错误,原因是我使用selectMany:无法将类型“System.Linq.IQueryable”隐式转换为“System.Linq.IQueryable”,我应该选择分组的。selectMany可以将所有数据组合在一起,对吗?方法的返回类型与
GroupBy
语句的返回类型不匹配。您必须相应地更改方法的返回类型。但是,这很可能不会更改SQL输出。我如何更改groupby的返回类型,因为我无法更改方法的返回类型,返回类型t,U是在groupby之前从属性生成的lambda表达式。您无法更改
groupby
的返回类型。这就是
SelectMany
的作用。在这种情况下,你必须坚持你所拥有的。
SELECT [e].[Year]
FROM [org].[Data] AS [e]
GROUP BY [e].[Year]
SELECT [e].[Id]
FROM [org].[Data] AS [e]
WHERE [e].[Year] = --Value