Entity Framework создает разные SQL в зависимости от того, где запускается программа

1

Я создал небольшое консольное приложение С#, задачей которого является только синтаксический анализ XML файла и поместить результат в таблицу базы данных. Я использую Entity framework 6.0 и.NET 4.

Все нормально, когда я запускаю его на своем локальном компьютере (Win7), но когда я запускаю его на сервере (WS2008R2), он сбой. Это те же самые файлы, которые только что копируются/вставляются на сервер (т.е. та же база данных и т.д.).

Отладка показывает, что SQL-запрос создается по-разному с помощью Entity Framework в зависимости от того, в какой среде он выполняется. (Смотри ниже)

ON LOCAL COMPUTER (работает нормально):

INSERT [dbo].[Accessories]([Id], [Name], [Category], [Price], [Description], [Phone_Id])
VALUES (@0, @1, @2, @3, @4, NULL)
@0: '1018' (Type = Int32)
@1: 'H141/A Headset Duoset' (Type = String, Size = -1)
@2: 'Headset Fixed Lines' (Type = String, Size = -1)
@3: '1563' (Type = Int32)
@4: 'H141/A DuoSet, Plantronics headset.' (Type = String, Size = -1)
Executing 
Completed in 19 ms with result: 1

ON SERVER (Не работает):

INSERT [dbo].[Accessories]([Name], [Category], [Price], [Description], [Phone_Id])
VALUES (@0, @1, @2, @3, NULL)
SELECT [Id]
FROM [dbo].[Accessories]
WHERE @@ROWCOUNT > 0 AND [Id] = scope_identity()
@0: 'H141/A Headset Duoset' (Type = String, Size = -1)
@1: 'Headset Fixed Lines' (Type = String, Size = -1)
@2: '1563' (Type = Int32)
@3: 'H141/A DuoSet, Plantronics headset.' (Type = String, Size = -1)
Executing 
Failed in 1 ms with error: Cannot insert the value NULL into column 'Id', table 'Sales.dbo.Accessories'; column does not allow nulls. INSERT fails.
The statement has been terminated.

АКТУАЛЬНЫЙ КОД В ПРИМЕНЕНИИ:

           try
           {
               XmlNodeList xNodeList = xDoc.SelectNodes("accessories/child::node()");
               foreach (XmlNode xNode in xNodeList)
               {
                   if (xNode.Name == "accessory")
                   {
                       var accessory = new Accessory();
                       accessory.Id = Convert.ToInt32(xNode.Attributes["id"].Value);
                       foreach (XmlNode childNode in xNode.ChildNodes)
                       {
                           if (childNode.Name == "name")
                           {
                               accessory.Name = childNode.InnerText;
                           }
                           if (childNode.Name == "category")
                           {
                               accessory.Category = childNode.InnerText;
                           }
                           if (childNode.Name == "description")
                           {
                               accessory.Description = childNode.InnerText;
                           }
                           if (childNode.Name == "price")
                           {
                               accessory.Price = Convert.ToInt32(childNode.InnerText);
                           }
                       }
                       _db.Add(accessory);
                   }
               }
               _db.SaveChanges();

SQL-сервер - MSSQL.

Я немного здесь потерял.. что делать?

  • 0
    Знаете ли вы, что SQL Server имеет разные версии? Проверьте их - я уверен, что у вас есть разные версии с обеих сторон. Сторона БД не идентична.
  • 0
    Как побочный комментарий, вы, вероятно, могли бы заменить всю эту функцию каким-нибудь красивым Linq to XML.
Показать ещё 1 комментарий
Теги:
sql-server
entity-framework-6

3 ответа

0
Лучший ответ

Это было решением нашей проблемы, я не уверен, почему, но вот она:

Мы забыли установить базовый интерфейс.

Database.SetInitializer(new CustomContextInitializer());

который теперь требует:

public class CustomContextInitializer : IDatabaseInitializer<CustomProjectContext>
{        
    public void InitializeDatabase(CustomProjectContext context)
    {
        context.Database.Initialize(false);
    }
}

Я предполагаю, что Entity или.NET выполняет некоторые собственные фоновые операции, если эта часть отсутствует, поэтому мы получили разные SQL-запросы в разных средах.

0

Если вы используете Code First (и я уверен, что вы есть), то остерегайтесь того, что разные версии Entity Framework (не разные версии SQL Server) используют тонко разные правила для сопоставления классов с таблицами. Одна вещь, которая зависит от точной версии EF, заключается в том, является ли Id целочисленного свойства автоматически без каких-либо спецификаций с вашей стороны, сопоставленному столбцу IDENTITY в базе данных. Если ваша база данных была создана с Id как обычный столбец без идентификатора, а ваш код изменил версии EF, так что теперь он ожидает столбец идентификации, все ломается.

Решение состоит в том, чтобы не смешивать версии EF. Выберите одну версию и придерживайтесь ее. Убедитесь, что версия используется на вашем локальном компьютере, а также тот, который вы используете на сервере. Убедитесь, что версия DLL файлов Entity Framework скопирована в каталог установки программы, не полагайтесь на что-либо, установленное во всем мире.

  • 0
    Сделал следующее: * Обновил EF до 6.1.1 * Удалил базу данных * Восстановил базу данных (используя EF) * Удалил все файлы на сервере * Скопировал все файлы из локального бина на сервер (включая EF dll) Тот же результат, что и раньше, выполнение локально работает, выполнить на сервере не удается ... :(
  • 0
    @ Груффалон Это странно. И если вы теперь проследите, чтобы получить запросы, которые на самом деле выполняются, они все еще различаются на локальном компьютере и сервере и остаются такими же, как вы видели изначально? Можете ли вы убедиться, проверив свойства typeof(DbContext).Assembly , что загружаемая DLL-библиотека Entity Framework действительно является той, которую вы хотите загрузить?
Показать ещё 3 комментария
0

Я думаю, что у вашей серверной версии базы данных не установлен параметр "Идентификация" для "Да" для вашего первичного ключа (Id). Таким образом, это не автоматическое генерирование идентификационного номера, и, поскольку вы не проходите его, это значит, что это ошибка в идентификаторе null.

  • 1
    Нет, OP проходит через ID, это Entity Framework, который его удаляет. Посмотрите SQL ОП, который генерируется на локальном компьютере: там указан идентификатор.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню