为什么我不能在LINQ to SQL中重用一个函数

sol*_*man 3 .net c# linq-to-sql

为什么下面的LINQ to SQL语句会抛出异常?

我有一个功能

bool TrimAndCompare(string s1, string s2)
{
   return customer.CustomerID.Trim() == customerID.Trim()
}
Run Code Online (Sandbox Code Playgroud)

...我在linq语句中调用上述函数的其他函数

var customers = from customer in _context.Customers
                          where
                              TrimAndCompare(customer.CustomerID, customerID)
                      select customer;
Run Code Online (Sandbox Code Playgroud)

上面的LINQ to SQL statment函数抛出一个异常但是下面没有为什么?

var customers = from customer in _context.Customers
                      where
                            customer.CustomerID.Trim() == customerID.Trim()
                      select customer;
Run Code Online (Sandbox Code Playgroud)

我得到一个'System.NotSupportedException',我尝试访问客户

Jon*_*eet 8

在第二个片段中,逻辑被转换为lambda表达式,然后将其编译成表达式树...两个查询翻译是:

_context.Customers
        .Where(customer => TrimAndCompare(customer.CustomerID, customerID);
Run Code Online (Sandbox Code Playgroud)

VS

_context.Customers
        .Where(customer => customer.CustomerID.Trim() == customerID.Trim());
Run Code Online (Sandbox Code Playgroud)

LINQ to SQL知道如何处理表达式树,它知道Trim和字符串相等.它知道如何处理对你编写的任意方法的调用.

最简单的方法可能是将方法更改为:

Expression<Func<Customer, bool>> CustomerIdMatches(string customerID)
{
   return customer => customer.CustomerID.Trim() == customerID.Trim()
}
Run Code Online (Sandbox Code Playgroud)

然后你可以使用:

from customer in context.Customers.Where(CustomerIdMatches(customerID))
... rest of query here
Run Code Online (Sandbox Code Playgroud)

或者您甚至可以使用自己的扩展方法来完成该Where部分.

使其更普遍地适用于不同领域是有点棘手的.特别是,它不能从查询表达式中很好地工作......它是可行的,但不是非常漂亮.

用法看起来像这样:

var query = context.Customers
                   .Where(TrimAndCompare(customer => customer.CustomerID,
                                         customer => customerID));
Run Code Online (Sandbox Code Playgroud)

不是非常好:(