我有一个非常简单的表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生成大小相当于其相应行的动态参数?
答案 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;}