У меня есть сценарий, в котором я хотел бы взаимодействовать с управляемыми данными 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