我正在使用Entity Framework 4.3.1,首先是代码,我正在查看正在生成的查询的SQL事件探查器。以下是一个例子:
如您所见 - 它将参数指定为nvarchar(max)
但在我的配置中我指定了MaxLength
值。因此,我希望参数将作为nvarchar(n)
传递。由于它没有这样做,我们发现查询运行缓慢,这个简单的更改会加快它们的速度。
有谁知道我们如何说服实体框架生成正确的nvarchar
长度?
这是我的实体和配置代码:
public class StorageTransportOrderItem
{
public string StorageTransportOrderItemNumber { get; set; }
public string StorageNumber { get; set; }
[...]
}
ToTable("StorageTransportOrderItem");
Property(p => p.StorageTransportOrderNumber)
.HasMaxLength(10);
Property(d => d.StorageTransportOrderItemNumber)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None)
.HasMaxLength(4);
HasKey(d => new
{
d.StorageTransportOrderItemNumber,
d.StorageNumber,
d.StorageTransportOrderNumber
});
FROM [dbo].[StorageTransportOrder] AS [Extent1]
WHERE ([Extent1].[StorageNumber] = @p__linq__0) AND ([Extent1]
[StorageTransportOrderNumber] = @p__linq__1)
) AS [Limit1]',N'@p__linq__0 nvarchar(max) ,@p__linq__1 nvarchar(max)
',@p__linq__0=N'200',@p__linq__1=N'0001374850'
注意nvarchar(max)
,这就是它变慢的原因。
答案 0 :(得分:3)
Tl:dr; 我不认为HasMaxLength()
,或者事实上你在使用Entity Framework时可以控制的任何东西都可以改变这一点,所以你可能应该看看在查询。
我的想法
我对你的查询获得nvarchar(max)
的原因感到有点困惑 - 我希望nvarchar(4000)
因为这是我在测试系统上得到的。这个问题提出了这个问题:Why does code first/EF use 'nvarchar(4000)' for strings in the raw SQL command?(非常有趣的阅读,那一个)。也许与ADO .Net版本有关,我不确定。
Anyhoo,我说我会建议你不能影响这个价值(至少,我相信你可以说服它nvarchar(4000)
而不是nvarchar(max)
当然但不是别的什么)。
我认为在生成这些查询时,Entity Framework正在使用ADO .NET中的自动参数化功能(请参阅:How Data Access Code Affects Database Performance)。从本质上讲,我说我怀疑他们只是将字符串值添加到ADO .NET DbParameter
并完成它。
这是一个真正的耻辱,因为你已经指定了MaxLength
它确实知道该字段有多长,但我也可以想象用列来计算Lambda表达式中的参数有多复杂它涉及到,所以我并不完全惊讶。
那你能做什么?
鉴于你无法改变这一点,虽然它确实会影响性能,但正如你的建议,我建议你专注于减少运行这类查询的数量。通常,通过调整查询结构和计数而不是像这样的小事来做最好的性能改进(仅仅是我的经验,不要把它当作福音)。
例如,如果您在循环中执行类似SingleOrDefault(i => i.id ==x)
的操作,则可能需要将其转换为循环外的单个Where(i => xs.Contains(i.id))
。那种事。我不能真正详细说明,但我相信你将能够使用其他方法来获得足够的表现。
祝你好运!