Часто задаваемые вопросы (LINQ to SQL)

В следующих разделах даны ответы на некоторые вопросы, которые могут возникнуть при реализации LINQ.

Решение других проблем рассматривается в разделе Устранение неполадок (LINQ to SQL).

Не удается подключиться

В. Не удается соединиться с базой данных.

О. Проверьте, правильно ли указана строка соединения и запущен ли экземпляр SQL Server. Обратите внимание, что для LINQ to SQL требуется включенный протокол именованных каналов. Дополнительные сведения см. в разделе Обучение с помощью пошаговых руководств (LINQ to SQL).

Потеряны изменения, внесенные в базу данных

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

О. Проверьте, что для сохранения результатов в базе данных был вызван метод SubmitChanges.

Как долго сохраняется открытым соединение с базой данных?

В. Как долго соединение с базой данных будет оставаться открытым?

О. Как правило, подключение остается открытым до тех пор, пока не будут использованы результаты запроса. Если планируется выделить время для обработки и кэширования всех результатов, к запросу следует применить ToList<TSource>. В типичных сценариях, где каждый объект обрабатывается только один раз, потоковая модель является предпочтительной в DataReader и LINQ to SQL.

Точные сведения об использовании подключения зависят от следующих моментов.

  • Состояние подключения, если DataContext создан с помощью объекта подключения.

  • Параметры строки подключения (например, включение режима MARS). Дополнительные сведения см. в разделе Режим MARS.

Обновление без выполнения запросов

В. Можно ли обновить данные таблицы, не отправляя запрос в базу данных?

О. Хотя в LINQ to SQL отсутствуют команды обновления на основе наборов, для обновления без выполнения запроса можно воспользоваться любым из следующих способов.

  • Чтобы отправить код SQL, используйте ExecuteCommand.

  • Создайте новый экземпляр объекта и инициализируйте все текущие значения (поля), влияющие на обновление. Затем прикрепите объект к DataContext с помощью Attach и отредактируйте поле, которое нужно изменить.

Неожиданные результаты запроса

В. Запрос возвращает непредвиденные результаты. Как узнать, что случилось?

О. LINQ to SQL предусматривает несколько средств для проверки создаваемого кода SQL. Одним из наиболее важных Log. Дополнительные сведения см. в разделе Поддержка отладки (LINQ to SQL).

Неожиданные результаты хранимой процедуры

В. Имеется хранимая процедура, возвращаемое значение которой вычислено с помощью функции MAX(). При перетаскивании процедуры в область Реляционный конструктор объектов возвращаемое значение становится неверным.

О. LINQ to SQL обеспечивает два способа возврата значений, сформированных в базе данных, с помощью хранимых процедур.

  • Путем именования выходного результата.

  • Путем явного указания выходного параметра.

Ниже представлен пример неверных выходных данных. Поскольку LINQ to SQL не может сопоставить результаты, он всегда возвращает 0.

create procedure proc2

as

begin

select max(i) from t where name like 'hello'

end

Ниже представлен пример правильных выходных данных с использованием выходного параметра.

create procedure proc2

@result int OUTPUT

as

select @result = MAX(i) from t where name like 'hello'

go

Ниже представлен пример правильных выходных данных с именованием выходного результата.

create procedure proc2

as

begin

select nax(i) AS MaxResult from t where name like 'hello'

end

Дополнительные сведения см. в разделе Настройка операций с помощью хранимых процедур (LINQ to SQL).

Ошибки сериализации

В. При попытке выполнения сериализации возвращается следующее сообщение об ошибке: «Тип System.Data.Linq.ChangeTracker+StandardChangeTracker... не отмечен как сериализуемый».

О. Формирование кода в LINQ to SQL поддерживает сериализацию DataContractSerializer. Оно не поддерживает XmlSerializer или BinaryFormatter. Дополнительные сведения см. в разделе Сериализация (LINQ to SQL).

Несколько DBML-файлов

В. При работе с несколькими DBML-файлами, использующими общие таблицы, возникает ошибка компилятора.

О. В каждом DBML-файле установите свойства Пространство имен контекста и Пространство имен сущности из Реляционный конструктор объектов в разные значения. Это способ исключает конфликты имен/пространств имен.

Предупреждение явного задания значений, созданных базой данных, в Insert или Update

В. В базе данных имеется таблица со столбцом DateCreated, в качестве значения по умолчанию которой указана функция SQL Getdate(). При попытке вставить новую запись с помощью LINQ to SQL возвращается значение NULL. Хотя ожидается заданное по умолчанию значение базы данных.

О. LINQ to SQL автоматически обрабатывает данную ситуацию для столбцов identity (автоувеличение), rowguidcol (формируемые базой данных идентификаторы GUID) и timestamp. В других случаях свойствам IsDbGenerated=true и AutoSync=Always/OnInsert/OnUpdate следует задать значения вручную.

Несколько параметров DataLoadOptions

В. Можно ли задать дополнительные параметры загрузки, не переопределяя исходные?

О. Да. Исходные параметры не переопределяются, как показано в следующем примере.

Dim dlo As New DataLoadOptions()
dlo.LoadWith(Of Order)(Function(o As Order) o.Customer)
dlo.LoadWith(Of Order)(Function(o As Order) o.OrderDetails)
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<Order>(o => o.Customer);
dlo.LoadWith<Order>(o => o.OrderDetails);

Ошибки при использовании SQL Compact 3.5

В. При перетаскивании таблиц из базы данных SQL Server Compact 3.5 возникает ошибка.

О. Реляционный конструктор объектов, в отличие от среды выполнения LINQ to SQL, не поддерживает SQL Server Compact 3.5. В этом случае необходимо создать собственные классы сущностей и добавить соответствующие атрибуты.

Ошибки в связях наследования

В. При использовании фигуры наследования панели элементов в Реляционный конструктор объектов для соединения двух объектов возникают ошибки.

О. Простого создания связи недостаточно. Необходимо предоставить сведения, такие как столбец дискриминатора, значение дискриминатора базового класса и значение дискриминатора производного класса.

Модель поставщика

В. Доступна ли модель общего поставщика?

О. Такая модель отсутствует. В настоящий момент LINQ to SQL поддерживает только SQL Server и SQL Server Compact 3.5.

Атаки путем внедрения кода SQL

В. Каким образом LINQ to SQL защищен от атак путем внедрения кода SQL?

О. Внедрение SQL-кода представляло серьезную угрозу для традиционных SQL-запросов, создаваемых путем объединения данных, вводимых пользователем. LINQ to SQL предотвращает подобное внедрение за счет использования в запросах объектов SqlParameter. Вводимые данные преобразуются в значения параметров. Этот способ исключает использование вредоносных команд из введенных данных.

Создание флага "Только чтение" в файлах DBML.

В. Как можно избавиться от некоторых методов задания свойств при создании объектной модели из файла DBM?

О. Выполните следующие действия.

  1. В файле DBML измените свойство, присвоив флагу IsReadOnly значение True.

  2. Добавьте разделяемый класс. Создайте конструктор с параметрами для членов, доступных только для чтения.

  3. Проверьте значение по умолчанию UpdateCheck (Never), чтобы определить, является ли оно правильным для приложения.

    Предупреждающее замечаниеВнимание

    При использовании Реляционный конструктор объектов в Visual Studio изменения могут быть переопределены.

APTCA

В. Помечена ли сборка System.Data.Linq для использования кодом с частичным доверием?

О. Да, сборка System.Data.Linq.dll входит в число сборок .NET Framework, отмеченных атрибутом AllowPartiallyTrustedCallersAttribute. Без данной отметки сборки в .NET Framework предназначены для использования только полностью доверенным кодом.

Основной сценарий в LINQ to SQL, разрешающий частично доверенный вызывающий код, предусматривает разрешение доступа к сборке LINQ to SQL из веб-приложений, причем для уровня доверия установлено значение «Средний».

Дополнительные сведения см. в следующем разделе. Управление доступом для кода в ASP.NET и Управление доступом для кода в ASP.NET.

Сопоставление данных из нескольких таблиц

В. Данные в сущность поступают из нескольких таблиц. Как их сопоставить?

О. В базе данных можно создать представление и сопоставить с ним сущность. LINQ to SQL создает одинаковый SQL-код для представлений и таблиц.

ПримечаниеПримечание

В данном сценарии использование представлений имеет ограничения.Способ работает с максимальной безопасностью, если операции, выполняемые в Table<TEntity>, поддерживаются базовым представлением.Операции, которые предполагается использовать, известны только вам.Например, большинство приложений доступно только для чтения, а другая значительная часть выполняет действия Create/Update/Delete только при использовании хранимых процедур в представлениях.

Организация пулов соединений

В. Существует ли конструкция, которая поможет в организации пула объектов DataContext?

О. Не пытайтесь повторно использовать экземпляры DataContext. Каждый DataContext сохраняет состояние (включая кэш идентификации) для одного определенного сеанса редактирования/запроса. Для получения новых экземпляров на основе текущего состояния базы данных используйте новый DataContext.

Можно по-прежнему использовать базовое объединение подключений ADO.NET. Дополнительные сведения см. в разделе Организация пулов соединений SQL Server (ADO.NET).

Не выполняется обновление второго DataContext

В. Для хранения значения в базе данных использовался один экземпляр DataContext. Однако второй DataContext в той же базе данных не отражает обновленные значения. Второй экземпляр DataContext, вероятно, возвращает кэшированные значения.

О. Это сделано намеренно. LINQ to SQL по-прежнему возвращает те же экземпляры и значения, которые отображались в первом экземпляре. При выполнении обновлений используется оптимистическая блокировка. Для проверки текущего состояния базы данных используются исходные данные, которые подтверждают неизменность ее состояния. Если состояние изменилось, возникает конфликт, который должен быть устранен приложением. Одним вариантом является сброс исходного состояния до текущего состояния базы данных и повторная попытка обновления. Дополнительные сведения см. в разделе Как управлять конфликтами изменений (LINQ to SQL).

Кроме того, ObjectTrackingEnabled можно задать значение «false», которое отключает кэширование и отслеживание изменений. После этого самые последние значения можно будет извлекать при каждом запросе.

Не удается вызвать метод SubmitChanges в режиме "только чтение"

В. При попытке вызова метода SubmitChanges в режиме только для чтения возникает ошибка.

О. Режим только для чтения отключает для контекста возможность отслеживания изменений.

См. также

Задачи

Устранение неполадок (LINQ to SQL)

Основные понятия

Безопасность в LINQ to SQL

Другие ресурсы

Справочник (LINQ to SQL)