查询Linq-to-SQL更新值[pre-SubmitChanges()]

时间:2010-11-23 18:00:49

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

我有一个场景,我希望与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数据不同的结果。

DDL

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

1 个答案:

答案 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...
}

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