Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.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/8/linq/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# 无法根据从表达式返回表达式的用法推断方法的类型参数_C#_Linq - Fatal编程技术网

C# 无法根据从表达式返回表达式的用法推断方法的类型参数

C# 无法根据从表达式返回表达式的用法推断方法的类型参数,c#,linq,C#,Linq,我试图从Select返回一个表达式,所以我有一个表达式返回一个表达式(我想-可能是lambda返回一个表达式,我不确定术语) 如果我创建了一个变量,它显式地为表达式提供了一个类型,那么它就可以工作,例如 housingDivisions.Select(id => { Expression<Func<Document, bool>> expression = d => d.HousingDivisions.Any(h => h.HousingDiv

我试图从Select返回一个表达式,所以我有一个表达式返回一个表达式(我想-可能是lambda返回一个表达式,我不确定术语)

如果我创建了一个变量,它显式地为表达式提供了一个类型,那么它就可以工作,例如

housingDivisions.Select(id => {
    Expression<Func<Document, bool>> expression = d => d.HousingDivisions.Any(h => h.HousingDivisionId == id);
    return expression;
})
但会导致编译错误:

错误CS0411无法从用法推断方法“Enumerable.Select(IEnumerable,Func)”的类型参数。尝试显式指定类型参数


有没有办法在不创建不必要的变量的情况下进行编译?

问题在于
d
类型和
d=>…
的委托类型都是未知的,不能从任何地方假定。通过实例化委托类型,可以一次性解决这两个问题:

housingDivisions.Select(id => new Func<Document, bool>(d => d.HousingDivisions.Any(h => h.HousingDivisionId == id)))
housingDivisions.Select(id=>newfunc(d=>d.housingDivisions.Any(h=>h.housingdivision id==id)))
如果绝对需要将类型转换为表达式树,则可以通过强制转换将其转换为:

housingDivisions.Select(id => (Expression<Func<Document, bool>>)(d => d.HousingDivisions.Any(h => h.HousingDivisionId == id)))
housingDivisions.Select(id=>(表达式)(d=>d.housingDivisions.Any(h=>h.HousingDivisionId==id)))
编译器建议显式指定参数。就我个人而言,我认为这种方式有点罗嗦。但它看起来是这样的:

housingDivisions.Select<int, Expression<Func<Document, bool>>>(id => d => d.HousingDivisions.Any(h => h.HousingDivisionId == id));
housingDivisions.Select(id=>d=>d.housingDivisions.Any(h=>h.HousingDivisionId==id));

以下是选择表达式的扩展方法:

public static IEnumerable<Expression<Func<ExprArg, Result>>> SelectExpr<TSource, ExprArg, Result>(this IEnumerable<TSource> source, Func<TSource, ExprArg, Result> func)
{
    return source.Select((o) => (Expression<Func<ExprArg, Result>>)((arg) => func(o, arg)));
}


// Use:
housingDivisions.SelectExpr((int id, Document d) => d.HousingDivisions.Any(h => h.HousingDivisionId == id));
public static IEnumerable SelectExpr(此IEnumerable源,Func Func)
{
返回源。选择((o)=>(表达式)((arg)=>func(o,arg));
}
//使用:
housingDivisions.SelectExpr((intid,documentd)=>d.housingDivisions.Any(h=>h.HousingDivisionId==id));

您是否尝试过显式指定要选择的类型参数?如果您需要经常这样做,您可以添加自己的扩展方法(
SelectExpression
或类似的方法),这可能会有所帮助。@JonSkeet我尝试了housingDivisions.Select(id=>(Document d=>d.housingDivisions.Any(h=>h.housingdivision id==id))但是我得到了同样的错误,那就是为lambda表达式指定参数类型。我建议按照Rhaokiel的回答指定类型参数。然而,如果你在很多地方都这样做的话,那就太好了。如果是,你总是返回一个
表达式
,或者函数的返回类型可能不同吗?@JonSkeet我在很多地方都使用这个方法,所以
SelectExpression
扩展方法是个好主意,但我还没有弄明白怎么做yetOkay,我可以用它写一个答案。lambda表达式总是返回bool吗?(请告诉我们
housingDivisions
Document.housingDivisions
HousingDivisionId
的类型好吗?)第二个选项很好,但理想情况下,它会更不冗长-这是一个很长的类型名,在代码中到处都是扩展方法的问题是表达式只是调用函数,因此EF不会将其转换为SQL,我得到
System.invalidoOperationException:'为警告生成的错误“Microsoft.EntityFrameworkCore.Query.QueryClientEvaluationWarning:LINQ表达式“where Invoke(_func_0,_o_1,[d])无法转换,将在本地进行计算。”
您正在走向复杂的。。。下面是为已经构建的表达式提供参数并减少参数以使LINQ能够转换为SQL所必须做的事情:老实说,我认为您最好找到一种使用LINQ的方法,而不是绕过它。是的,我在某个地方读到,唯一可以转换为本地集合的扩展方法是
Contains
,所以我设置逻辑的顺序以利用这一点。
public static IEnumerable<Expression<Func<ExprArg, Result>>> SelectExpr<TSource, ExprArg, Result>(this IEnumerable<TSource> source, Func<TSource, ExprArg, Result> func)
{
    return source.Select((o) => (Expression<Func<ExprArg, Result>>)((arg) => func(o, arg)));
}


// Use:
housingDivisions.SelectExpr((int id, Document d) => d.HousingDivisions.Any(h => h.HousingDivisionId == id));