EF6不将Func lambda识别为Where的筛选器



我有以下实体:

[Table("Customer", Schema = "dbo")]
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
}
[Table("Payment", Schema = "dbo")]
public class Payment
{
public int PaymentId { get; set; }
public int CustomerId { get; set; }
public DateTime Period { get; set; }
public int Price { get; set; }
[ForeignKey("CustomerId")]
public Customer Customer { get; set; }
}

现在我想用PeriodPrice来过滤Payment表。每个谓词都必须在自己的Where方法中。因此,我得到以下内容:

int price = 200;
var period = new DateTime(2020, 10, 3);
using var db = new TestContext();
// Option 1: anonymous lambda
var payments1 = db.Payments
.Where(p => p.Period < period)
.Where(p => p.Price <= price);
foreach (var payment in payments1)
{
listBox.Items.Add(
$"Payment: Payment Id={payment.PaymentId}, " +
$"Customer Id`={payment.CustomerId}, " +
$"Period={payment.Period.ToShortDateString()}, " +
$"Price={payment.Price}");
}

EF6生成正确的SQL:

exec sp_executesql N'SELECT 
[Extent1].[PaymentId] AS [PaymentId], 
[Extent1].[CustomerId] AS [CustomerId], 
[Extent1].[Period] AS [Period], 
[Extent1].[Price] AS [Price]
FROM [dbo].[Payment] AS [Extent1]
WHERE ([Extent1].[Period] < @p__linq__0) AND ([Extent1].[Price] <= @p__linq__1)',
N'@p__linq__0 datetime2(7),@p__linq__1 int',
@p__linq__0='2020-10-03 00:00:00',
@p__linq__1=200

但是,如果我使用Funclambda,条件相同:

// Option 2: Func<T, T> lambda
Func<Payment, bool> func = p => p.Period < period;
var payments2 = db.Payments.Where(func).Where(p => p.Price <= price);

我没有得到相同的SQL,但得到了这个:

SELECT 
[Extent1].[PaymentId] AS [PaymentId], 
[Extent1].[CustomerId] AS [CustomerId], 
[Extent1].[Period] AS [Period], 
[Extent1].[Price] AS [Price]
FROM [dbo].[Payment] AS [Extent1]

据我所知,EF转向了客户端评估。我想知道,为什么会发生这种事?我使用相同的lambda进行过滤!

您需要使用表达式,而不仅仅是函数这样EF才能计算出属性等的名称。

尝试:

Expression<Func<Payment, bool>> func = p => p.Period < period;

最新更新