5

我正在使用 Entity Framework 4.3.1,代码优先,并且正在 SQL Profiler 中查看正在生成的查询。这是一个例子:

如您所见 - 它正在指定参数,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),这就是让它变慢的原因。

4

1 回答 1

3

Tl:博士;我不认为HasMaxLength(),或者实际上你在使用Entity Framework时可以控制的任何东西都不能改变这一点,所以你可能应该查看查询。

我的想法

我对您为什么要进行查询感到有些困惑nvarchar(max)-我希望nvarchar(4000)这就是我在测试系统上得到的结果。这个问题问这个问题: 为什么代码优先/EF 在原始 SQL 命令中对字符串使用'nvarchar(4000)'?(相当有趣的阅读,那个)。也许与 ADO .Net 版本有关,我不确定。

Anyhoo,话虽如此,我将建议您将无法影响此值(至少,我相信您可以说服它,nvarchar(4000)而不是nvarchar(max)当然,而不是其他任何东西)。

认为实体框架在生成这些查询时使用了 ADO .NET 中的自动参数化功能(请参阅:数据访问代码如何影响数据库性能)。本质上,我是说我怀疑他们只是将字符串值添加到 ADO .NETDbParameter并完成它。

这真是太遗憾了,因为正如您所指定的那样,MaxLength它确实知道该字段的长度,但我也可以想象将 Lambda 表达式中的参数与其相关的列相加会有多复杂,所以我不是完全惊讶。

所以,你可以做什么?

鉴于您无法更改这一点,尽管它确实会影响性能,但正如您所建议的那样,我建议您集中精力减少运行的此类查询的数量。通常最好的性能改进是通过调整查询的结构和计数来实现的,而不是像这样的小事情(只是我的经验,不要把它当作福音)。

例如,如果您正在执行类似SingleOrDefault(i => i.id ==x)循环内的操作,您可能希望将其转换为Where(i => xs.Contains(i.id))循环外的单个操作。那种事。我不能真正详细说明,但我相信您将能够使用其他一些方法来获得足够的性能。

祝你好运!

于 2013-10-18T10:11:10.617 回答