Sql 如何强制Entity Framework 4.0生成与其相应数据库列大小相等的参数
我有一个非常简单的表,名为Sql 如何强制Entity Framework 4.0生成与其相应数据库列大小相等的参数,sql,linq,entity-framework,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
,它包括以下内容:
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从datacontext运行一个查询,如下所示:
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(32)
时,它会自动将成员外部ID列强制转换为varchar(8000)
。
有没有办法强制EF动态生成与其对应行大小相等的参数?似乎没有办法直接实现这一点。我假设它是一个内置功能,可以保证执行计划的一致性。同时,我用一个存储过程替换了查询。这种转换给我们带来了很多麻烦。经过一点调查,我们在映射类中映射了一些属性,以告诉EF该列并不像您想象的那么大 长度为8000个字符的SQL参数会大大降低查询性能。 我们没有在映射类中映射所有属性的长度,但我们在需要性能时进行了映射 您可以在EntityTypeConfiguration映射类中定义参数,如下所示(已测试): 也可以使用数据注释(未测试)
为什么将参数转换为varchar(8000)是次优的;我们的常驻DBA坚持认为它在内存分配方面是次优的。他没有说更多的细节。你的看法是什么?理论上他可能是对的,但现在8k并没有那么多,而且很可能很快就又没有分配了。运行几百次sql语句的两个变体,一个是varchar(8000),另一个是varchar(32),看看是否有任何性能差异。我认为在内存中保存变量会影响性能,因此如果我声明变量
varchar(8000)
,然后在内存中的一个地址保留8000字节来保存该值。我认为内存只在变量被赋值的点分配,因此如果我传递一个32字节大小的参数,那么LINQ参数只消耗32字节的内存。如果是这样,那就没问题了。但是,如果保留8000字节,不管持久化参数的大小如何,都需要进行优化。谢谢,我已经回顾了类似的技术,普遍的共识是性能影响可以忽略不计——据我所知,这只会在更新行时产生显著影响,可能会导致页面分割。不用太担心,因为我只是在读数据。尽管如此,我仍然想知道我是否可以强制LINQ生成的参数的大小。我认为EF团队应该基于模型实现正确的参数大小和类型。实施起来难吗?是否应向EF团队发送此类请求?你觉得呢?我不确定内奥米。在证明使用EF和direct SQL的合理性方面,这并不是一个很大的交易破坏者,但是DB管理员通常会将其视为一个需要优化的问题。我向EF团队提出了一个建议。如果您喜欢,请查看并投票。问题是不是说这根本不会影响SQL参数的大小?
Property(t => t.ExternalId)
.HasColumnName("Member_ExternalId")
.HasColumnType("varchar")
.HasMaxLength(32);
[Column(TypeName="varchar")]
[MaxLength(32)]
public string ExternalId {get; set;}