Запрос обновленных значений Linq-to-SQL [pre-SubmitChanges ()] - PullRequest
1 голос
/ 23 ноября 2010

У меня есть сценарий, в котором я хотел бы взаимодействовать с управляемыми данными Linq-to-Sql (VS2008 / .NET Framework 3.5 / Sql Server 2005 Express), который был обновлен, но еще не передан обратно в базу данных с помощью ' SubmitChanges ()».

Ниже приведен простой тестовый пример, в котором я изменяю свойство цвета для простого объекта «Блок». Я перечисляю таблицу (блоки 9 и 10 изначально имеют нулевые значения для цвета), меняю значения и перечисляю результаты, и все выглядит хорошо. Тем не менее, возникает некоторая странность (или пробелы в моем понимании), когда я пытаюсь запросить (.Count) объект 'Blocks', как это выделено в двух выделенных ниже жирных выражениях.

Инструкция LinqtoSqlDBDataContext.Blocks.Count (Block => Block.Color == null) приводит к значению '2' ..., что является нечетным, так как предыдущее перечисление показывает, что все блоки имеют назначенный цвет. Достигается ли это утверждение обратно в базу данных (где действительно «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

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

<strong>LinqtoSqlDBDataContext.Blocks.Count(Block => Block.Color == null) is 2</strong>

SELECT [t0].[ID], [t0].[Color]
FROM [dbo].[Block] AS [t0]
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.30729.1

<strong>LinqtoSqlDBDataContext.Blocks.ToList().Count(Block => Block.Color == null) is 0</strong>

Press [Enter] to continue

1 Ответ

0 голосов
/ 23 ноября 2010

Возможно, вам придется сериализовать результаты перед выполнением модификации, если вы хотите, чтобы значения сохранялись.EG

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

Таким образом, объекты будут сохранять свое состояние, хотя это может вызвать проблемы / требовать, чтобы вы вносили изменения по-другому.

...