Entity framework 如何在lambda表达式中调用自定义方法。我使用实体框架4。存储表达式错误

Entity framework 如何在lambda表达式中调用自定义方法。我使用实体框架4。存储表达式错误,entity-framework,lambda,entity-framework-4,Entity Framework,Lambda,Entity Framework 4,可以在lambda表达式中调用自定义方法吗 //Address a : It's an Entity public string AddressConstructor(Address a) { return a.City + "," + a.Province; } var Test = _db.MyTableTest.Select( t => new ViewModel {

可以在lambda表达式中调用自定义方法吗

//Address a : It's an Entity
public string AddressConstructor(Address a)
{
    return a.City + "," + a.Province;
}



var Test = _db.MyTableTest.Select( t => new ViewModel
                                   {
                                      MyID = t.ID,
                                      StringAddress = AddressConstructor(t.Addr)
                                   };

您应该能够使用LINQKit将表达式内联到表达式树中来实现这一点

这将导致您试图在SQL Server上运行的concatation,而不是在内存中运行,如另一个答案中所述。SQL Server当然知道如何关联字符串,但是如果您的AddressConstructor做了SQL Server不理解的其他事情,那么这种方法将不起作用,您确实需要使用另一个答案中描述的方法在内存中执行自定义方法

本质上,LINQKit会将树展平,使其实际执行为:

    var Test = _db.MyTableTest.Select( t => new ViewModel
 {
      MyID = t.ID,
      StringAddress = t.Addr.City + "," + t.Addr.Province
 };

哪个EF在执行时应该没有问题,连接应该在SQL Server上进行。

您应该能够使用LINQKit将表达式内联到表达式树中来实现这一点

这将导致您试图在SQL Server上运行的concatation,而不是在内存中运行,如另一个答案中所述。SQL Server当然知道如何关联字符串,但是如果您的AddressConstructor做了SQL Server不理解的其他事情,那么这种方法将不起作用,您确实需要使用另一个答案中描述的方法在内存中执行自定义方法

本质上,LINQKit会将树展平,使其实际执行为:

    var Test = _db.MyTableTest.Select( t => new ViewModel
 {
      MyID = t.ID,
      StringAddress = t.Addr.City + "," + t.Addr.Province
 };
哪个EF在执行时应该没有问题,连接应该发生在SQL Server上。

您需要调用AsEnumerable,以便在本地执行投影:

var Test = _db.MyTableTest.AsEnumerable()
                          .Select( t => new ViewModel
                                   {
                                      MyID = t.ID,
                                      StringAddress = AddressConstructor(t.Addr)
                                   };
否则,将使用Queryable.Select方法而不是Enumerable.Select方法,这会导致Entity Framework尝试将lambda表达式转换为SQL查询,在这种情况下,这当然是不可能的。您需要调用AsEnumerable,以便在本地执行投影:

var Test = _db.MyTableTest.AsEnumerable()
                          .Select( t => new ViewModel
                                   {
                                      MyID = t.ID,
                                      StringAddress = AddressConstructor(t.Addr)
                                   };

否则,将使用Queryable.Select方法而不是Enumerable.Select方法,这将导致Entity Framework尝试将lambda表达式转换为SQL查询,在这种情况下,这当然是不可能的

我将尝试一下,并让您知道。正如您所解释的,与我的IIS服务器相比,我最好在sql server端执行此任务。@Jean Francois,您永远无法在sql server上创建ViewModel实例,因为它甚至不知道此类型。。。这样的语句无法转换为SQL语句。这是正确的…您将无法在SQL Server上创建ViewModel的实例。那太傻了。但是,我建议他可以在SQL Server上连接字符串值,而在您的示例中,您是在内存中执行的。现在我了解了在SQL Server上执行操作与在内存中执行操作之间的区别。这两种技术都非常有效。Thomas Levesque建议的方法的一个巨大限制是,您将无法在SQL Server端对StringAddress进行筛选。您需要返回内存中的所有MyTableTest和filter,以便添加使用StringAddress的后续Where语句。我建议的方法是添加一个.Wherex=>x.StringAddress.Containsy并在SQL Server上执行,而不是返回所有行并在内存中执行。我会尝试一下,让您知道。正如您所解释的,与我的IIS服务器相比,我最好在sql server端执行此任务。@Jean Francois,您永远无法在sql server上创建ViewModel实例,因为它甚至不知道此类型。。。这样的语句无法转换为SQL语句。这是正确的…您将无法在SQL Server上创建ViewModel的实例。那太傻了。但是,我建议他可以在SQL Server上连接字符串值,而在您的示例中,您是在内存中执行的。现在我了解了在SQL Server上执行操作与在内存中执行操作之间的区别。这两种技术都非常有效。Thomas Levesque建议的方法的一个巨大限制是,您将无法在SQL Server端对StringAddress进行筛选。您需要返回内存中的所有MyTableTest和filter,以便添加使用StringAddress的后续Where语句。我建议的方法是添加一个.Wherex=>x.StringAddress.Containsy并在SQL Server上执行,而不是返回所有行并在内存中执行。我强烈建议查看下面的答案:,这实际上允许在SQL Server中执行所有这些。唯一的要求是自定义函数“AddressConstructor”足够简单,可以简化为与SQL Server兼容的基本操作。我强烈建议查看以下答案:,这实际上允许在SQL Server中执行所有操作。唯一的要求是自定义函数“AddressConstructor”足够简单,可以简化为 与SQL Server重新兼容。