Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server ';更新检查';对LINQ更新有什么建议_Sql Server_Linq_Updatecheck - Fatal编程技术网

Sql server ';更新检查';对LINQ更新有什么建议

Sql server ';更新检查';对LINQ更新有什么建议,sql-server,linq,updatecheck,Sql Server,Linq,Updatecheck,我有一个使用LINQ编辑的简单行。它有大约30列,包括一个主键数字序列 通过LINQ执行更新时,UPDATE语句包括表的所有列(用于并发检查) 我想知道这有多低效——如果不是疏忽的话。因为主键上有一个索引,所以我假设列用于初始行搜索,然后另外检查其他字段。我不会想到这会花费超过微不足道的时间 我问这个问题的原因是,我看到这个更新在某些情况下会占用一秒钟的时间,这似乎并不正确。可能还有其他长期运行的操作,但这让我好奇,我是否应该担心 我知道我可以将所有其他字段的“UpdateCheck”设置为“永

我有一个使用LINQ编辑的简单行。它有大约30列,包括一个主键数字序列

通过LINQ执行更新时,UPDATE语句包括表的所有列(用于并发检查)

我想知道这有多低效——如果不是疏忽的话。因为主键上有一个索引,所以我假设列用于初始行搜索,然后另外检查其他字段。我不会想到这会花费超过微不足道的时间

我问这个问题的原因是,我看到这个更新在某些情况下会占用一秒钟的时间,这似乎并不正确。可能还有其他长期运行的操作,但这让我好奇,我是否应该担心

我知道我可以将所有其他字段的“UpdateCheck”设置为“永不”,但这是一种痛苦

有没有办法关闭单个SubmitChanges()的“更新检查”,或者我必须通过更改每个字段的“更新检查”来完成

如有任何建议,将不胜感激

以下是SQL更新:

exec sp_executesql N'UPDATE [dbo].[SiteVisit]
SET [TotalTimeOnSite] = @p12, [ContentActivatedTime] = @p13
WHERE ([SiteVisitId] = @p0) AND ([SiteUserId] IS NULL) AND ([ClientGUID] = @p1) AND ([ServerGUID] IS NULL) AND ([UserGUID] = @p2) AND ([SiteId] = @p3) AND ([EntryURL] = @p4) AND ([CampaignId] = @p5) AND ([Date] = @p6) AND ([Cookie] IS NULL) AND ([UserAgent] = @p7) AND ([Platform] IS NULL) AND ([Referer] = @p8) AND ([KnownRefererId] = @p9) AND ([FlashVersion] IS NULL) AND ([SiteURL] IS NULL) AND ([Email] IS NULL) AND ([FlexSWZVersion] IS NULL) AND ([HostAddress] IS NULL) AND ([HostName] IS NULL) AND ([InitialStageSize] IS NULL) AND ([OrderId] IS NULL) AND ([ScreenResolution] IS NULL) AND ([TotalTimeOnSite] IS NULL) AND ([CumulativeVisitCount] = @p10) AND ([ContentActivatedTime] IS NULL) AND ([ContentCompleteTime] IS NULL) AND ([MasterVersion] = @p11) AND ([VisitedHome] IS NULL) AND ([VisitedStore] IS NULL) AND ([VisitedVideoDemos] IS NULL) AND ([VisitedProducts] IS NULL) AND ([VisitedAdvantages] IS NULL) AND ([VisitedGallery] IS NULL) AND ([VisitedTestimonials] IS NULL) AND ([VisitedEvolution] IS NULL) AND ([VisitedFAQ] IS NULL)',N'@p0 int,@p1 uniqueidentifier,@p2 uniqueidentifier,@p3 int,@p4 varchar(46),@p5 varchar(3),@p6 datetime,@p7 varchar(164),@p8 varchar(36),@p9 int,@p10 int,@p11 int,@p12 int,@p13 int',@p0=1009772,@p1='039A0614-31EE-4DD9-9E1A-8A0F947E1719',@p2='C83C0E68-142A-47CB-B7F9-BAF462E79429',@p3=1,@p4='http://www.example.com/default.aspx?c=183',@p5='183',@p6='2008-11-30 18:22:59:047',@p7='Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; SIMBAR={85B62341-3F6B-4645-A473-53A2D2BB66DC}; FunWebProducts; .NET CLR 1.1.4322; InfoPath.1; .NET CLR 2.0.50727)',@p8='http://apps.facebook.com/inthemafia/',@p9=1,@p10=1,@p11=30,@p12=6,@p13=6

我们在堆栈溢出时很早就遇到了这个问题。每次LINQ到SQL更新都会在写入更新之前验证底层字段是否没有更改。换句话说,每次更新都是“仅当此字段等于且此字段等于且此字段等于时才更新记录”

我们决定大部分时间不关心悲观更新,更新需要检查的唯一字段是Id字段

因此,我们为每个字段设置了
UpdateCheck=“never”
,dbml映射文件中的Id除外,如下所示:

<Type Name="Badge">
  <Column Name="Id" Type="System.Int32" DbType="Int NOT NULL IDENTITY"
      IsPrimaryKey="true" IsDbGenerated="true" CanBeNull="false" />
  <Column Name="Class" Type="System.Byte" DbType="TinyInt NOT NULL"
      CanBeNull="false" UpdateCheck="Never" />
  <Column Name="Name" Type="System.String" DbType="VarChar(50) NOT NULL" 
      CanBeNull="false" UpdateCheck="Never" />


我不知道是否有一种方法可以通过编程或动态完成这项工作。

就我个人而言,我喜欢单一时间戳/行版本列的简单性;将此列设置为唯一要检查的列(IIRC,对于
timestamp
自动发生),然后您将被排序-然后您将获得TSQL,如:

exec sp_executesql N'UPDATE [dbo].[SiteVisit]
SET [TotalTimeOnSite] = @p2, [ContentActivatedTime] = @p3
WHERE ([SiteVisitId] = @p0) AND ([Timestamp] = @p1)

这取决于它们对同一记录的更新不是并发的(非冲突的);对于时间戳/行版本等,任何冲突的更新都会导致第二次中止,即使它们更新了不同的列等。

时间戳字段显然是最优雅的方式。我讨厌弄乱单个字段的属性——主要是为了安全地删除一个表并将其重新添加到我的DBML文件中,而不必担心结果

现在为更新生成的SQL为:

exec sp_executesql N'UPDATE [dbo].[SiteVisit]
SET [TotalTimeOnSite] = @p2
WHERE ([SiteVisitId] = @p0) AND ([timestamp] = @p1)
在同一交易中:

SELECT [t1].[timestamp]
FROM [dbo].[SiteVisit] AS [t1]
WHERE ((@@ROWCOUNT) > 0) AND ([t1].[SiteVisitId] = @p3)',N'@p0 int,@p1 timestamp,@p2 int,@p3 int',@p0=814109,@p1=0x0000000000269CB8,@p2=1199920,@p3=814109

它执行更新,然后检索新的时间戳以发送回我的客户机。我不确定自己是否完全理解@@ROWCOUNT>0的含义,但现在我真的不在乎:)

您关于更新检查的开销可以忽略不计的断言是正确的。如果where子句的任何部分都满足索引(或主键),则将使用该索引。检查其他列的成本可以忽略不计。您可以通过在SQL management studio(或SQL Server早期版本的查询分析器)中启用执行计划显示并运行更新来确认这一点


执行时间长很可能是由其他原因造成的。锁定是一个很好的选择。如果可以复制该模式,请使用SQL事件探查器查明发生了什么。

如果可以修改该模式,请添加rowversion类型的列。最新的LINQ to SQL将所有列的更新检查设置为从不。如果您有一个时间戳,它将使用它作为乐观锁检查,并且系统会在每次有更新时对其进行缓冲


注意:这曾经是SQL'92定义的时间戳数据类型,但是实现它时没有任何时间信息,因此它与任何其他标准系统都不兼容。也许这是故意的,谁知道呢

stackoverflowy类型问题的一个非常stackoverflowy的解决方案:-)我选择了时间戳解决方案,因为我不想每次更新模式时都要更改每一列。这是一种编程方式:通过反射修改内部结构。一旦模型开始有100个表,这就有意义了。有“最新”版本吗。NET3.5SP1?我没有意识到这一点,我相信最新版本被称为LINQtoEntities??LINQtoSQL!=林克托-Entities@Simon:(@@ROWCOUNT)>0)返回上一个查询中受影响的行数。在这种情况下,如果一行被实际更新,查询将只返回更新的时间戳(否则,@ROWCOUNT将等于0)。这样,如果你没有在你的应用程序中得到时间戳,你就知道更新失败了。竖起大拇指点击链接!很好!