![](/img/trans.png)
[英]How to pass Func to a class which encapsulates the Expression based on that Func?
[英]How to pass variables to Expression Func Projection before compile
我正在尝试为我的投影编写表达函数。 我找到了一篇有关该链接的好文章。 但是我不知道如何将变量传递给这些函数。
我如何为此编写一个投影函数
int i = 3;
var query = await _db.Users
.FilterByName(name)
.Select(item => new SearchResultItemViewModel
{
Id = item.Id,
Article = item.FirstName + i.ToString()
});
}))
这个正在工作。 在选择SQL字符串中只有Id和Firstname,但是我不能传递任何变量。
var query = await _db.Users
.FilterByName(name)
.Select(item => SearchResultItemViewModel.Projection)
public static Expression<Func<ApplicationUser, SearchResultItemViewModel>> Projection
{
get
{
return item => new SearchResultItemViewModel
{
Id = item.Id,
Article = item.FirstName
};
}
}
仅当您调用编译和调用时,此命令才有效。 SQL字符串包含所有行。 导致性能不佳
var query = await _db.Users
.FilterByName(name)
.Select(item => SearchResultItemViewModel.Projection.Compile().Invoke(item,i))
public static Expression<Func<ApplicationUser,int, SearchResultItemViewModel>> Projection
{
get
{
return( item,i) => new SearchResultItemViewModel
{
Id = item.Id,
Article = item.FirstName + i.ToString()
};
}
}
我不使用EF,因此在您的特定用例中可能会有所不同,但这似乎是有关LINQ表达式的一个问题,而不是其他任何问题。
第一个大问题是,您尝试使用Expression<Func<ApplicationUser, int, SearchResultItemViewModel>>
,实际上您的意思是Expression<Func<ApplicationUser, SearchResultItemViewModel>>
而这并没有做您想要的事情。 而不是绑定到变量,而是调用Select
的索引变体 。 因此,您不必为所有行都获得相同的i
值,而是获得行的索引。
创建引用变量的表达式时,会发生以下两种情况之一。 对于局部变量(和参数),该值将复制到绑定到该表达式的匿名类实例,因此您之后将无法对其进行更改。 对于其他变量,表达式包含对变量本身的引用,以及非静态变量的包含对象。
这意味着您原则上可以使用静态变量来更改参数,而不必重新创建投影表达式。 当然有时候这很有用。
另一方面,每次访问Projection
属性时,上面的代码都会创建一个新实例。 那么,为什么不将其更改为函数并在需要时生成所需的表达式呢?
public static Expression<Func<ApplicationUser, SearchResultItemViewModel>> Projection(int parm)
=> item => new SearchResultItemViewModel
{
Id = item.Id,
Article = item.FirstName + parm.ToString()
};
每次调用该方法时,都将返回一个使用指定值的表达式。
或者,您也可以使用表达式访问者来获取模板表达式并将其常量修改为您当时需要的任何值。 好玩,但我认为这里有点超出范围。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.