И снова очередная проблема с Entity Framework 6.0.x после добавления его в проект через NuGet.
После запуска приложения, при первом обращении к данным, вылетает исключение следующего содержиния:
The Entity Framework provider type 'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer' registered in the application config file for the ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded. Make sure that the assembly-qualified name is used and that the assembly is available to the running application. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information.
Что говорит о том, что сборка EntityFramework.SqlServer не попадает в директорию сборки проекта. А ошибок при анализе кода Visual Studio не выдает, скорее всего, из-за того что Entity Framework использует позднее связывание с этой сборкой. Поэтому жестких ссылок на нее в коде Entity Framework не содержит. А подцепляется она в момент обращения к данным. В результате чего и генерируется исключение, что не удалось найти требуемую сборку.
Погуглив, понял, что проблема уже изъезженная. Например, тут, Rob Lang привел возможные варианты решения возникшей проблемы. Например:
В своей предыдущей статье Entity Framework 6.0.x и INotifyPropertyChanged я описал как можно править код скриптов, генерирующих код модели и контекста данных. Сейчас нам как раз надо модифицировать файл *.Content.tt, в котором содержится код описывающий алогритм генерации контекста данных.
Находим в нем следующие строчки и добавляем туда нужную нам строчку кода:
Теперь после любых изменений в модели данных, контекст данных будет всегода генерироваться нужным нам образом. Собственно, то что нам и надо.
После запуска приложения, при первом обращении к данным, вылетает исключение следующего содержиния:
The Entity Framework provider type 'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer' registered in the application config file for the ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded. Make sure that the assembly-qualified name is used and that the assembly is available to the running application. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information.
Что говорит о том, что сборка EntityFramework.SqlServer не попадает в директорию сборки проекта. А ошибок при анализе кода Visual Studio не выдает, скорее всего, из-за того что Entity Framework использует позднее связывание с этой сборкой. Поэтому жестких ссылок на нее в коде Entity Framework не содержит. А подцепляется она в момент обращения к данным. В результате чего и генерируется исключение, что не удалось найти требуемую сборку.
Погуглив, понял, что проблема уже изъезженная. Например, тут, Rob Lang привел возможные варианты решения возникшей проблемы. Например:
- Указать Visual Studio явно ложить эту сборку в выходную директорию проекта, куда он билдится.
- Добавить в конструткор контекста данных Entity Framework строчку кода, где создавать пустую переменную со ссылкой на объект класса из этой сборки. И при сборке проекта, Visual Studio увидит эту зависимость и положить в выходную директорию нужную нам сборку.
Второй вариант более предпочтительный, т.к. отказавшить от Entity Framework мы автоматом не будем получать в выходной директории проекта уже не нужную нам сборку. Поэтому, если погуглить, то большинство решений сводится к этому варианту.
Для фикса этой баги, я добавил статичный класс, в котором добавил метод, инициирующий переменную со ссылкой на объект типа из сборки EntityFramework.SqlServer.
public static class EF_FIX { public static void FixEfProviderServicesProblem() { //The Entity Framework provider type 'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer' //for the 'System.Data.SqlClient' ADO.NET provider could not be loaded. //Make sure the provider assembly is available to the running application. //See http://go.microsoft.com/fwlink/?LinkId=260882 for more information. var instance = System.Data.Entity.SqlServer.SqlProviderServices.Instance; } }Дальше, нам необходимо прописать вызов этого метода в конструкторе контекста данных Entity Framework:
public partial class DB : DbContext { public DB() : base("name=DB") { EF_FIX.FixEfProviderServicesProblem(); }Но тут получаем еще одну не очень приятную вещь. После каждого обновления модели Entity Framework класс контекста данных будет обновляться и наша строчка кода будет пропадать. И нам ее надо будет в таких ситуациях не забывать каждый раз прописывать заново, что не удобно.
В своей предыдущей статье Entity Framework 6.0.x и INotifyPropertyChanged я описал как можно править код скриптов, генерирующих код модели и контекста данных. Сейчас нам как раз надо модифицировать файл *.Content.tt, в котором содержится код описывающий алогритм генерации контекста данных.
Находим в нем следующие строчки и добавляем туда нужную нам строчку кода:
EF_FIX.FixEfProviderServicesProblem();Получаем следующее:
<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext { public <#=code.Escape(container)#>() : base("name=<#=container.Name#>") { EF_FIX.FixEfProviderServicesProblem(); <# if (!loader.IsLazyLoadingEnabled(container)) { #> this.Configuration.LazyLoadingEnabled = false; <# }После сохранения код контекста данных обновится и в нем тоже появится наш заветный фикс бага.
Теперь после любых изменений в модели данных, контекст данных будет всегода генерироваться нужным нам образом. Собственно, то что нам и надо.
Комментариев нет:
Отправить комментарий