4

我有一个非常简单的表Member,它由以下内容组成:

CREATE TABLE [dbo].[Member](
    [Member_MemberId] [int] IDENTITY(1000,1) NOT NULL,
    [Member_ExternalId] [varchar](32) NULL,
    [Member_ConsumerId] [varchar](32) NULL,
 CONSTRAINT [PK_Member] PRIMARY KEY NONCLUSTERED 
(
    [Member_MemberId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

我正在使用 EF 4.0 从数据上下文运行查询,如下所示:

return Members.SingleOrDefault(member => member.ExternalId == externalId);

生成的 SQL 如下所示:

exec sp_executesql N'SELECT TOP (2) 
[Extent1].[Member_MemberId] AS [Member_MemberId], 
[Extent1].[Member_ExternalId] AS [Member_ExternalId], 
[Extent1].[Member_ConsumerId] AS [Member_ConsumerId]
FROM [dbo].[Member] AS [Extent1]
WHERE [Extent1].[Member_ExternalId] = @p__linq__0',N'@p__linq__0 varchar(8000)',@p__linq__0='Paul'

varchar(8000)从性能 POV 来看,此查询是次优的,因为当列本身限制为 时,它会自动将 Member_ExternalId 列强制转换为varchar(32)。有没有办法强制 EF 生成大小与其相应行等效的动态参数?

4

2 回答 2

1

似乎没有办法直接实现这一点。我认为这是一个内置功能,可以保证执行计划的一致性。与此同时,我已经用存储过程替换了查询。

于 2012-07-02T16:22:43.843 回答
-1

我们在这种转变中遭受了很多痛苦。经过一番调查,我们在映射类中映射了一些属性,以告诉 EF 该列并不像您想象的那么大。

具有 8000 个字符长度的 SQL 参数会大大降低查询性能。我们没有在映射类中映射所有属性的长度,而是在需要性能时进行映射。

您可以像这样(经过测试)在 EntityTypeConfiguration 映射类中定义您的参数:

Property(t => t.ExternalId)
    .HasColumnName("Member_ExternalId")
    .HasColumnType("varchar")
    .HasMaxLength(32);

或者您可以使用数据注释(未测试)

[Column(TypeName="varchar")]
[MaxLength(32)]
public string ExternalId {get; set;}
于 2021-05-18T12:21:13.020 回答