我有一个场景,我希望与Linq-to-Sql托管数据(VS2008 / .NET Framework 3.5 / Sql Server 2005 Express)进行交互,该数据已更新,但尚未通过'提交回数据库'的SubmitChanges()”
我在下面给出了一个简单的测试用例,其中我在一个简单的'Block'对象上更改了一个color属性。我列举了表(块9和10最初具有Color的空值),更改值,并枚举结果,所有看起来都很好。但是,当我尝试查询(.Count)下面两个粗体输出语句中突出显示的“Blocks”对象时,会出现一些奇怪的现象(或者我的理解上的差距)。
语句 LinqtoSqlDBDataContext.Blocks.Count(Block => Block.Color == null)导致值为'2'...这是奇怪的,因为前一个枚举显示所有块具有指定的颜色。这个陈述是否可以追溯到数据库(确实'2'将是一个正确的值,因为还没有提交)? db跟踪确认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数据不同的结果。
SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET ANSI_PADDING ON GO CREATE TABLE [dbo].[Block]( [ID] [int] IDENTITY(1,1) NOT NULL, [Color] [varchar](50) NULL, CONSTRAINT [PK_Table1] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO SET ANSI_PADDING OFF
using System; using System.Collections.Generic;co using System.Linq; using System.Text; using System.Data.Linq; namespace LinqToSql1 { class Program { static void Main(string[] args) { LinqtoSqlDBDataContext LinqtoSqlDBDataContext = new LinqtoSqlDBDataContext(); LinqtoSqlDBDataContext.Log = Console.Out; Console.WriteLine("Enumerating Blocks\n=================="); foreach(Block Block in LinqtoSqlDBDataContext.Blocks) { Console.WriteLine("Block {0} Color is '{1}'", Block.ID, Block.Color); } Console.WriteLine(); Console.WriteLine("Updating Blocks\n==============="); foreach(Block Block in LinqtoSqlDBDataContext.Blocks.Where(b => b.Color == null)) { Console.WriteLine("Block {0} Color was '{1}'", Block.ID, Block.Color); Block.Color = "Gray"; Console.WriteLine("Block {0} Color is '{1}'", Block.ID, Block.Color); } Console.WriteLine(); Console.WriteLine("Enumerating Blocks\n=================="); foreach(Block Block in LinqtoSqlDBDataContext.Blocks) { Console.WriteLine("Block {0} Color is '{1}'", Block.ID, Block.Color); } Console.WriteLine(); // Console.WriteLine("Submitting Changes\n=================="); // LinqtoSqlDBDataContext.SubmitChanges(); Console.WriteLine("Counting Blocks\n==============="); Console.WriteLine("LinqtoSqlDBDataContext.Blocks.Count(Block => Block.Color == null) is {0}\n", LinqtoSqlDBDataContext.Blocks.Count(Block => Block.Color == null)); Console.WriteLine("LinqtoSqlDBDataContext.Blocks.ToList().Count(Block => Block.Color == null) is {0}\n", LinqtoSqlDBDataContext.Blocks.ToList().Count(Block => Block.Color == null)); LinqtoSqlDBDataContext.Dispose(); Console.WriteLine("Press [Enter] to continue"); Console.ReadLine(); } } }
Enumerating Blocks ================== SELECT [t0].[ID], [t0].[Color] FROM [dbo].[Block] AS [t0] -- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.30729.1 Block 1 Color is 'Red' Block 2 Color is 'Green' Block 3 Color is 'Yellow' Block 4 Color is 'Black' Block 5 Color is 'Orange' Block 6 Color is 'Purple' Block 7 Color is 'Blue' Block 8 Color is 'White' Block 9 Color is '' Block 10 Color is '' Updating Blocks =============== SELECT [t0].[ID], [t0].[Color] FROM [dbo].[Block] AS [t0] WHERE [t0].[Color] IS NULL -- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.30729.1 Block 9 Color was '' Block 9 Color is 'Gray' Block 10 Color was '' Block 10 Color is 'Gray' Enumerating Blocks ================== SELECT [t0].[ID], [t0].[Color] FROM [dbo].[Block] AS [t0] -- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.30729.1 Block 1 Color is 'Red' Block 2 Color is 'Green' Block 3 Color is 'Yellow' Block 4 Color is 'Black' Block 5 Color is 'Orange' Block 6 Color is 'Purple' Block 7 Color is 'Blue' Block 8 Color is 'White' Block 9 Color is 'Gray' Block 10 Color is 'Gray' Counting Blocks =============== SELECT COUNT(*) AS [value] FROM [dbo].[Block] AS [t0] WHERE [t0].[Color] IS NULL -- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.30729.1 LinqtoSqlDBDataContext.Blocks.Count(Block => Block.Color == null) is 2 SELECT [t0].[ID], [t0].[Color] FROM [dbo].[Block] AS [t0] -- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.30729.1 LinqtoSqlDBDataContext.Blocks.ToList().Count(Block => Block.Color == null) is 0 Press [Enter] to continue
答案 0 :(得分:0)
如果要保留值,则可能必须在执行修改之前序列化结果。 E.G。
Console.WriteLine("Updating Blocks\n===============");
var blocksToUpdate = LinqtoSqlDBDataContext.Blocks.Where(b => b.Color == null).ToArray();
foreach( var block in blocksToUpdate )
{
// do something...
}
这样对象将保留其状态,但这可能会导致问题/要求您以不同方式进行提交更改。