c# - EF + LINQ : How do I define and utilize a variable (maybe a Func variable) to define part of a Select statement?

标签 c# entity-framework linq entity-framework-6 linq-to-entities

在尝试使用变量之前(这有 sql server 进行计算):

IQueryable<MyEntity> query = _dbSet; // IQueryable<TEntity>
var results = query.Select(m => new MyViewModel
{
    MyCalculation = m.Column1 * m.Column2
}).ToList();

我想做什么(从 Func 变量或某种其他类型的变量动态创建我的选择语句的一部分以允许这样做):

IQueryable<MyEntity> query = _dbSet; // IQueryable<TEntity>
Func<MyEntity, decimal> funcVariableAttempt = m => m.Column1 * m.Column2;
var results = query.Select(m => new MyViewModel
{
    MyCalculation = funcVariableAttempt.Invoke(m) // My foolish attempt does not work.
}).ToList();

当我尝试我想要的(也就是我的愚蠢尝试)时我得到的错误:

LINQ to Entities does not recognize the method 'System.Decimal Invoke(MyProject.Repository.Models.MyEntity)' method, and this method cannot be translated into a store expression.

如何定义和使用变量(可能是 Func 变量)来定义 Select 语句的一部分?

最佳答案

这是一个完全有效的问题,我之前偶然发现并找到了适合我的解决方案。

你的 Func<MyEntity, decimal> 的问题是它是一个委托(delegate),并且 O/R 映射器必须能够访问内部表达式(在您的情况下是两个属性的乘积)。但是这些信息被编译到委托(delegate)中并永远隐藏。

如果您从 Expression<Func<MyEntity, decimal>> customCalculation 开始,事情看起来更有希望,因为您将内部逻辑作为表达式树。 问题是:您不能调用表达式。 customCalculation(m)不编译。

编译器会让你写

m => new MyViewModel { MyCalculation = customCalculation.Compile()(m) }

,但这不会被大多数 O/R 映射器理解。

但您看到它至少以某种方式包含 customCalculation lambda 表达式及其与周围表达式的关系。

从这里到原始工作版本中的表达式树涉及一些表达式操作:

我们必须替换customCalculation.Compile()(m) lambda 的 bodyCompile() d,但将 lambda 的参数替换为委托(delegate)调用的相应表达式。所以如果customCalculationx => x.Column1 * x.Column2 , customCalculation.Compile()(m)必须替换为 m.Column1 * m.Column2

这样做并不简单,因为 lambda 本身必须从编译器生成的闭包类实例中的字段中挖掘出来。

我已经发布了这个表达式操纵器的实现 in another similar question .希望对您有所帮助。

有了它,您应该能够:

var customCalculation = (Expression<Func<MyEntity, decimal>>)(x => x.Column1 * x.Column2);
var selector = Express.Prepare((Expression<Func<MyEntity, MyViewModel>>)(m => new MyViewModel { MyCalculation = customCalculation.Compile()(m) }));
var result = query.Select(selector).ToList();

关于c# - EF + LINQ : How do I define and utilize a variable (maybe a Func variable) to define part of a Select statement?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45557061/

相关文章:

c# - 将声明转换与 Windows 身份验证结合使用

c# - 使用 MVC3 以相同的形式上传多个图像

mysql - Entity Framework /SQL - 排除多列数据

c# - MVC 从缓存或旧数据库中提取数据

C#:合并数据表中的数据行

java - 使用 JIRA 版本 3.12 创建 JIRA 票证

c# - 使 .Net 3.5 应用程序与 .Net 4.0 应用程序对话的最稳定方式

c# - 使用 Entity Framework 替换选择的字符串

c# - LINQ Group By 以及包含元素的列表的百分比

c# - 从两个不同的词典中获取相同的键