Linq to sql 使用从linq到sql查询的校验和索引
我有一个表,在nvarcharMAX列上有一个索引,用作计算列。SQL查询可以使用带有文本值及其校验和的WHERE子句来使用此索引 查询如何使用此索引 我查看了和及其答案,即单个值的校验和。 但是SqlFunctions.Checksumimportant会引发异常: 此函数只能从LINQ调用到实体 这种行为与Checksumstring文档中的描述完全相同 在表中,可通过以下方式定义:Linq to sql 使用从linq到sql查询的校验和索引,linq-to-sql,sqlserver,linqpad,c#,link-to-sql,link-to-entities,sql-server,linq,Linq To Sql,Sqlserver,Linqpad,C#,Link To Sql,Link To Entities,Sql Server,Linq,我有一个表,在nvarcharMAX列上有一个索引,用作计算列。SQL查询可以使用带有文本值及其校验和的WHERE子句来使用此索引 查询如何使用此索引 我查看了和及其答案,即单个值的校验和。 但是SqlFunctions.Checksumimportant会引发异常: 此函数只能从LINQ调用到实体 这种行为与Checksumstring文档中的描述完全相同 在表中,可通过以下方式定义: CREATE TABLE [Tags]( [TagId] [uniqueidentifier] NO
CREATE TABLE [Tags](
[TagId] [uniqueidentifier] NOT NULL PRIMARY KEY,
[Tag] [nvarchar](max) NOT NULL,
[TagHash] AS (checksum([Tag])) PERSISTED
)
以及通过以下途径获取索引:
CREATE INDEX [IX_Tags] ON [Tags] (
[TagHash] ASC
)
以下SQL查询可能使用index1:
此查询表达式尝试在中引发NotSupportedException:
如何在中构造上述查询,而不使用类似的构造
1这取决于查询优化器。如果您可以修改数据库并更改Linq2Sql模型,那么您可以通过创建自己的sql函数来包装校验和来实现这一点。比如说
Create FUNCTION dbo.MyCheckSum (@input NVarChar(max)) RETURNS int
AS
BEGIN
Declare @output int
select @output = CheckSum(@input)
return @output
End
然后你可以像这样使用它
from tag in Tags
where MyChecksum("important") == tag.Hash && "important" == tag.Tag
select tag
如果你不能修改你的数据库或模型,你可以有一个适合你的例子的变通方法,以牺牲另一个数据库命中率为代价,例如
int checkSum this dc.ExecuteQuery<int>("select Checksum('important')").Single();
from tag in Tags
where checkSum == tag.Hash && "important" == tag.Tag
select tag
而不是编写一个关于校验和的通用包装器 您可以编写一个访问器函数,通过校验和索引访问表:
CREATE FUNCTION TagsByName(
@key nvarchar(max))
RETURNS TABLE
AS
RETURN SELECT
[TagId],
[Tag],
[TagHash]
FROM Tags
WHERE CHECKSUM(@key) = [TagHash] AND
@key = [Tag];
与此相比,all和SQL查询的优点是可以通过TVF访问表,并且不使用索引和校验和。缺点是每个校验和索引构造都需要自己的TVF,而在单个TVF中就足够了
int checkSum this dc.ExecuteQuery<int>("select Checksum('important')").Single();
from tag in Tags
where checkSum == tag.Hash && "important" == tag.Tag
select tag
CREATE FUNCTION TagsByName(
@key nvarchar(max))
RETURNS TABLE
AS
RETURN SELECT
[TagId],
[Tag],
[TagHash]
FROM Tags
WHERE CHECKSUM(@key) = [TagHash] AND
@key = [Tag];