如何强制Entity Framework 4.0生成与其对应的数据库列等效大小的参数

时间:2012-07-02 13:55:50

标签: sql linq entity-framework

我有一个非常简单的表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]

我正在使用来自datacontext的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'

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

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:-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;}