В следующих разделах рассматриваются некоторые распространенные проблемы, которые могут возникнуть при реализации LINQ.
В устранении неполадок рассматриваются дополнительные проблемы.
Не удается подключиться
Не удается подключиться к базе данных.
Убедитесь, что строка подключения верна и экземпляр SQL Server запущен. Обратите внимание также, что LINQ to SQL требует включения протокола именованных каналов. Для получения дополнительной информации см. Обучение путем пошагового руководства.
Изменения в потерянной базе данных
Я внес изменения в данные в базе данных, но когда я перезапустил своё приложение, изменения исчезли.
Убедитесь, что вы вызовете SubmitChanges, чтобы сохранить результаты в базе данных.
Сколько времени открыто подключение к базе данных?
Сколько времени подключение к базе данных остается открытым?
Подключение обычно остается открытым, пока вы не получаете результаты запроса. Если вы ожидаете, что потребуется время для обработки всех результатов и не против кэширования результатов, примените ToList к запросу. В распространенных сценариях, когда каждый объект обрабатывается только один раз, модель потоковой обработки превосходит как DataReader, так и LINQ to SQL.
Точные сведения об использовании подключения зависят от следующих сведений:
Состояние подключения, если DataContext создан с помощью объекта подключения.
Параметры строки подключения (например, включение нескольких активных результирующих наборов (MARS). Дополнительные сведения см. в разделе Несколько активных результирующих наборов (MARS).
Обновление без запроса
Можно ли обновить данные таблицы без первого запроса к базе данных?
Хотя у LINQ to SQL нет команд обновления на основе набора, можно использовать любой из следующих методов для обновления без первого запроса:
Используется ExecuteCommand для отправки кода SQL.
Создайте новый экземпляр объекта и инициализируйте все текущие значения (поля), влияющие на обновление. Затем подключите объект к DataContext нему с помощью Attach и измените поле, которое необходимо изменить.
Непредвиденные результаты запроса
Мой запрос возвращает непредвиденные результаты. Как проверить, что происходит?
LINQ to SQL предоставляет несколько средств для проверки кода SQL, который он создает. Одним из наиболее важных является Log. Дополнительные сведения см. в разделе "Поддержка отладки".
Непредвиденные результаты выполнения хранимой процедуры
У меня есть хранимая процедура, возвращаемое значение которой вычисляется с помощью `MAX()`. При перетаскивании хранимой процедуры в область конструктора O/R возвращаемое значение неверно.
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
Дополнительные сведения см. в разделе "Настройка операций с помощью хранимых процедур".
Ошибки сериализации
При попытке сериализации я получаю следующую ошибку: "Тип System.Data.Linq.ChangeTracker+StandardChangeTracker" ... не помечен как сериализуемый".
Генерация кода в LINQ to SQL поддерживает DataContractSerializer сериализацию. Он не поддерживает XmlSerializer и BinaryFormatter. Дополнительные сведения см. в разделе Сериализация.
Несколько ФАЙЛОВ DBML
При наличии нескольких файлов DBML, которые совместно используют некоторые таблицы, возникает ошибка компилятора.
Задайте свойства пространства имен контекста и пространства имен сущностей из реляционного конструктора объектов в отдельное значение для каждого файла DBML. Этот подход устраняет конфликт имен и пространств имен.
Избежание явного задания значений, сгенерированных базой данных при вставке или обновлении
У меня есть таблица базы данных с столбцом DateCreated, который по умолчанию используется для SQL Getdate(). При попытке добавить новую запись с помощью LINQ to SQL, значение становится NULL. Ожидается, что оно будет соответствовать значению по умолчанию в базе данных.
LINQ to SQL обрабатывает эту ситуацию автоматически для идентификаторов (автоинкремент), rowguidcol (GUID, созданных базой данных) и столбцов метки времени. В других случаях следует вручную задать IsDbGenerated=trueиAutoSync=Always/OnInsert/OnUpdateсвойства.
Несколько параметров загрузки данных
Можно ли указать дополнительные параметры загрузки без перезаписи первого?
Да. Первый не перезаписан, как показано в следующем примере:
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 возникает ошибка.
Средство разработки объектов реляционной базы данных не поддерживает SQL Server Compact 3.5, хотя среда выполнения LINQ to SQL поддерживает. В этой ситуации необходимо создать собственные классы сущностей и добавить соответствующие атрибуты.
Ошибки в отношениях наследования
Я использовал наследуемую фигуру из панели инструментов в конструкторе объектно-реляционных отношений, чтобы соединить два объекта, но я получаю ошибки.
Создать отношения недостаточно. Необходимо предоставить такую информацию, как столбец дискриминатора, значение дискриминатора базового класса и значение дискриминатора производного класса.
Модель поставщика
Доступна ли модель общедоступного поставщика?
Модель общедоступного поставщика не доступна. В настоящее время LINQ to SQL поддерживает только SQL Server и SQL Server Compact 3.5.
Атаки SQL-инъекции
Каким образом LINQ to SQL защищается от атак внедрения SQL?
Внедрение SQL было значительным риском для традиционных запросов SQL, сформированных путем объединения входных данных пользователей. LINQ to SQL избегает такого внедрения, используя SqlParameter в запросах. Входные данные пользователя превратились в значения параметров. Этот подход предотвращает использование вредоносных команд из ввода клиентов.
Изменение флага только для чтения в DBML-файлах
Как исключить сеттеры из некоторых свойств при создании объектной модели из файла DBML?
Выполните следующие действия для этого расширенного сценария:
В DBML-файле измените свойство, изменив флаг IsReadOnlyна
True.Добавьте частичный класс. Создайте конструктор с параметрами для элементов только для чтения.
Проверьте значение по умолчанию UpdateCheck (Never), чтобы определить, является ли это правильным значением для приложения.
Осторожность
Если вы используете реляционный конструктор объектов в Visual Studio, изменения могут быть перезаписаны.
APTCA
Помечен ли System.Data.Linq для использования частично доверенным кодом?
Да, сборка System.Data.Linq.dll входит в число сборок .NET Framework, помеченных атрибутом AllowPartiallyTrustedCallersAttribute . Без этой маркировки сборки в .NET Framework предназначены только для использования полностью доверенным кодом.
Основной сценарий использования LINQ to SQL для предоставления доступа частично доверенным вызывающим объектам заключается в дозволении доступа к сборке LINQ to SQL из веб-приложений, когда уровень конфигурации доверия является средним.
Сопоставление данных из нескольких таблиц
Данные моего объекта поступают из нескольких таблиц. Как сопоставить?
Вы можете создать представление в базе данных и сопоставить сущность с представлением. 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 продолжает возвращать одни и те же объекты и значения, которые вы видели в первый раз. При внесении обновлений используется оптимистическое параллелизм. Исходные данные используются для проверки текущего состояния базы данных для утверждения о том, что он на самом деле остается неизменным. Если он изменился, конфликт возникает, и приложение должно устранить его. Одним из вариантов приложения является сброс исходного состояния в текущее состояние базы данных и повторная попытка обновления. Дополнительные сведения см. в статье "Управление конфликтами изменений".
Вы также можете задать ObjectTrackingEnabled значение false, которое отключает кэширование и отслеживание изменений. Затем можно получить последние значения при каждом запросе.
Не удается вызвать SubmitChanges в режиме только для чтения
При попытке вызвать SubmitChanges в режиме только для чтения возникает ошибка.
Режим только для чтения отключает возможность контекста отслеживать изменения.