【问题标题】:Querying Linq-to-SQL updated values [pre-SubmitChanges()]查询 Linq-to-SQL 更新值 [pre-SubmitChanges()]
【发布时间】:2011-05-14 15:20:45
【问题描述】:

我有一个场景,我想与已更新但尚未提交回数据库的 Linq-to-Sql 托管数据(VS2008/.NET Framework 3.5/Sql Server 2005 Express)进行交互 '提交更改()'。

我在下面给出了一个简单的测试用例,其中我正在更改一个简单的“块”对象的颜色属性。我枚举了表格(第 9 块和第 10 块最初的颜色为空值),更改值,并枚举结果,一切似乎都很好。但是,当我尝试查询(.Count)以下两个粗体输出语句中突出显示的“块”对象时,会出现一些奇怪的现象(或我的理解上的差距)。

语句 LinqtoSqlDBDataContext.Blocks.Count(Block => Block.Color == null) 导致值为 '2' ...这很奇怪,因为前面的枚举显示所有 Block分配了颜色。该语句是否返回到数据库(实际上 '2' 将是一个正确的值,因为尚未提交任何内容)?似乎数据库跟踪确认了 SELECT 语句。

第二条语句 LinqtoSqlDBDataContext.Blocks.ToList().Count(Block => Block.Color == null) 返回正确的值 '0',但我不确定为什么'ToList()' 会影响结果。正如您将注意到的,该语句还会生成一个完全不同的 SQL 语句(没有 WHERE 子句可引导)。

如果 SubmitChanges() 行未注释 LinqtoSqlDBDataContext.Blocks.Count(Block => Block.Color == null) 确实返回正确的值。但是,我不能总是预测我的更改量,并且希望尽可能轻松地考虑我返回数据库进行更新的次数。

所以我想我的问题是……根据我在这里看到的情况,与预先提交的数据进行交互是否安全/有效/推荐。我已经进行了广泛的搜索,但没有找到关于这种情况的太多(如果有的话)。有什么明显我想念的东西吗?任何和所有想法都非常感激。

总结:枚举预提交的 Linq-to-Sql 数据似乎返回的结果与查询预提交的 Linq-to-Sql 数据不同。

DDL

设置 ANSI_NULLS ON 走 设置 QUOTED_IDENTIFIER ON 走 设置 ANSI_PADDING ON 走 创建表 [dbo].[块]( [ID] [int] IDENTITY(1,1) 非空, [颜色] [varchar](50) NULL, 约束 [PK_Table1] 主键集群 ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) 开 [主要] 走 设置 ANSI_PADDING 关闭

代码

使用系统; 使用 System.Collections.Generic;co 使用 System.Linq; 使用 System.Text; 使用 System.Data.Linq; 命名空间 LinqToSql1 { 课堂节目 { 静态无效主要(字符串 [] 参数) { LinqtoSqlDBDataContext LinqtoSqlDBDataContext = new LinqtoSqlDBDataContext(); LinqtoSqlDBDataContext.Log = Console.Out; Console.WriteLine("枚举块\n==================="); foreach(LinqtoSqlDBDataContext.Blocks 中的块块) { Console.WriteLine("块 {0} 颜色为 '{1}'", Block.ID, Block.Color); } Console.WriteLine(); Console.WriteLine("更新块\n==============="); foreach(LinqtoSqlDBDataContext.Blocks.Where 中的块块(b => b.Color == null)) { Console.WriteLine("块 {0} 颜色为 '{1}'", Block.ID, Block.Color); Block.Color = "灰色"; Console.WriteLine("块 {0} 颜色为 '{1}'", Block.ID, Block.Color); } Console.WriteLine(); Console.WriteLine("枚举块\n==================="); foreach(LinqtoSqlDBDataContext.Blocks 中的块块) { Console.WriteLine("块 {0} 颜色为 '{1}'", Block.ID, Block.Color); } Console.WriteLine(); // Console.WriteLine("提交更改\n=================="); // LinqtoSqlDBDataContext.SubmitChanges(); Console.WriteLine("计数块\n==============="); Console.WriteLine("LinqtoSqlDBDataContext.Blocks.Count(Block => Block.Color == null) 是 {0}\n", LinqtoSqlDBDataContext.Blocks.Count(Block => Block.Color == null)); Console.WriteLine("LinqtoSqlDBDataContext.Blocks.ToList().Count(Block => Block.Color == null) 是 {0}\n", LinqtoSqlDBDataContext.Blocks.ToList().Count(Block => Block.Color = =空)); LinqtoSqlDBDataContext.Dispose(); Console.WriteLine("按 [Enter] 继续"); Console.ReadLine(); } } }

输出

枚举块 =================== 选择 [t0].[ID]、[t0].[颜色] FROM [dbo].[块] AS [t0] -- 上下文:SqlProvider(Sql2005) 模型:AttributedMetaModel 构建:3.5.30729.1 块 1 颜色为“红色” 块 2 颜色为“绿色” 第 3 块颜色为“黄色” 第 4 块颜色为“黑色” 块 5 颜色为“橙色” 第 6 块颜色为“紫色” 块 7 颜色是“蓝色” 第 8 块颜色为“白色” 第 9 块颜色为 '' 第 10 块颜色为 '' 更新块 ================ 选择 [t0].[ID]、[t0].[颜色] FROM [dbo].[块] AS [t0] WHERE [t0].[Color] 为空 -- 上下文:SqlProvider(Sql2005) 模型:AttributedMetaModel 构建:3.5.30729.1 第 9 块颜色为“” 第 9 块颜色为“灰色” 块 10 颜色是 '' 第 10 块颜色为“灰色” 枚举块 =================== 选择 [t0].[ID]、[t0].[颜色] FROM [dbo].[块] AS [t0] -- 上下文:SqlProvider(Sql2005) 模型:AttributedMetaModel 构建:3.5.30729.1 块 1 颜色为“红色” 块 2 颜色为“绿色” 第 3 块颜色为“黄色” 第 4 块颜色为“黑色” 块 5 颜色为“橙色” 第 6 块颜色为“紫色” 块 7 颜色是“蓝色” 第 8 块颜色为“白色” 第 9 块颜色为“灰色” 第 10 块颜色为“灰色” 计数块 ================ 选择 COUNT(*) 作为 [值] FROM [dbo].[块] AS [t0] WHERE [t0].[Color] 为空 -- 上下文:SqlProvider(Sql2005) 模型:AttributedMetaModel 构建:3.5.30729.1 LinqtoSqlDBDataContext.Blocks.Count(Block => Block.Color == null) 为 2 选择 [t0].[ID]、[t0].[颜色] FROM [dbo].[块] AS [t0] -- 上下文:SqlProvider(Sql2005) 模型:AttributedMetaModel 构建:3.5.30729.1 LinqtoSqlDBDataContext.Blocks.ToList().Count(Block => Block.Color == null) 为 0 按 [Enter] 继续

【问题讨论】:

  • 我认为这一定是他们构建列表的方式中的一个错误。看起来收集和迭代增量(更新)对象列表与原始成员之间的区别。或者它可能会检查“hasChanged”标志并默认为原始或虎钳诗句。

标签: c# sql-server linq-to-sql sql-server-express


【解决方案1】:

如果您希望保留这些值,则可能必须在进行修改之前对结果进行序列化。例如

Console.WriteLine("Updating Blocks\n===============");
var blocksToUpdate = LinqtoSqlDBDataContext.Blocks.Where(b => b.Color == null).ToArray();
foreach( var block in blocksToUpdate )
{
 // do something...
}

这样对象将保留其状态,尽管这可能会导致问题/需要您以不同的方式进行提交更改。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-28
    • 2013-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多