2011-12-25 2 views
4

Сначала я начал пробовать свои руки с кодом EF4 сегодня, и я создал свои классы POCO, данных и инициализаторы в отдельной библиотеке классов, я считаю, что это обычный код типа плиты котла. Я ссылаюсь на класс в приложении MVC3 и устанавливаю инициализатор в Global.asax. При запуске приложения я замечаю следующие проблемы:
1. Никакая база данных не создается нигде (тогда я добавляю запись в файле web.config для строки соединения, названной в честь класса Context, все равно никакого результата)
2. Когда я попробуйте получить доступ к инициализированным значениям, я получаю нулевую ошибку, очевидно, потому что нет данных.Код элемента Entity Framework Сначала в библиотеке классов

Может кто-нибудь, пожалуйста, помогите мне с указателями о том, как получить Тхи вещь, чтобы работать (было бы стыдно, если бы я провел весь мой рождественский день обучения это, и я до сих пор не могу заставить его работать :() Спасибо
пс я попытался вставить точки останова, и я попал в методе инициализации приложения, но он никогда не попадет в метод Seed в инициализаторе, даже если я добавить точку останова там, как хорошо !!
Спасибо.
Initializer класса

using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 
    using System.Data.Entity; 
    using F2AController.Models; 

    namespace F2AController.DataObjects 
    { 
     public class F2AInitializer : DropCreateDatabaseAlways<F2AContext> 
     { 
      protected override void Seed(F2AContext context) 
      { 
       var countries = new List<Country> 
       { 
        new Country(){ CountryName="Germany", Active = true}, 
        new Country(){ CountryName="Britain", Active = true} 
       }; 
       countries.ForEach(s => context.Countries.Add(s)); 
       context.SaveChanges(); 
       var providers = new List<Providers>() 
       { 
        new Providers(){ ProviderName="InfoBip", ContactDetails="Rturo Manovic", Active=true, MessageRates= new List<ProviderRates>(){new ProviderRates(){ CountryId=1, DateCreated=DateTime.Now, DateModified=DateTime.Now, Rate=0.05M, Active=true}}} 
       }; 
       providers.ForEach(p => context.Providers.Add(p)); 
       context.SaveChanges(); 
       var usermobiles = new List<MobileTerminal>() 
       { 
        new MobileTerminal(){ Active= true, Credits=200, DateCreated=DateTime.Now, MSISDN="4477565444865"} 
       }; 
       usermobiles.ForEach(u => context.MobileTerminals.Add(u)); 

       context.SaveChanges(); 
      } 


     } 
    } 

Контекстный класс

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Data.Entity; 

namespace F2AController.Models 
{ 
    public class F2AContext : DbContext 
    { 
     public DbSet<Country> Countries; 
     public DbSet<MobileTerminal> MobileTerminals; 
     public DbSet<Providers> Providers; 
     public DbSet<ProviderRates> ProviderRates; 
     public DbSet<Property> Properties; 
     public DbSet<ShortMessage> ShortMessages; 
     public DbSet<UserProperties> UserProperties; 

     protected override void OnModelCreating(DbModelBuilder modelBuilder) 
     { 
      base.OnModelCreating(modelBuilder); 
     } 
    } 
} 

Global.asax App метод инициализации

protected void Application_Start() 
    { 
     AreaRegistration.RegisterAllAreas(); 
     Database.DefaultConnectionFactory = new SqlConnectionFactory(ConfigurationManager.ConnectionStrings["F2AContext"].ConnectionString); 
     Database.SetInitializer<F2AContext>(new F2AInitializer()); 

     RegisterGlobalFilters(GlobalFilters.Filters); 
     RegisterRoutes(RouteTable.Routes); 
    } 
+0

Как насчет размещения класса инициализатора? или, по крайней мере, класс контекста. – LueTm

ответ

4

Eureka..finally!
При поиске решения я наткнулся на это сообщение Entity Framework Database.SetInitializer simply not working
Применяя решение, предлагаемое там, чтобы заставить мою базу данных создавать работу при запуске, как я и ожидал, но затем при запуске семенного кода он выбрал исключение с нулевым указателем. При исследовании я понял, что любая попытка ссылки на коллекции DBSet из класса Context дала то же исключение. Осматривая в дальнейшем я понял, что вместо того, чтобы использовать

public DbSet<MobileTerminal> MobileTerminals { get; set; } 

Я использовал

public DbSet<MobileTerminal> MobileTerminals; 

Это означало, что я не получил каких-либо неявной инициализации объекта, следовательно, исключения нулевого указателя. Я удалил принудительный код инициализации и снова запустил приложение, на этот раз начальный код не запустился, пока я не получил доступ к странице, которая фактически запросила контекст данных, и она отлично работала.
По-видимому, из-за Lazy загрузки код инициализации не запускается до тех пор, пока он не понадобится, то есть при первом запросе запроса данных в приложении.

Я надеюсь, что это поможет любому, у кого есть такая же проблема в будущем.

+0

Немного не по теме, но интересный для отладки использует приведенный выше код с 'DropCreateDatabaseIfModelChanges' вместо' DropCreateDatabaseAlways' (* face-palm * moment). Если вы пришли на эту страницу для этой проблемы, и вышеуказанное решение не работает, убедитесь, что вы этого не сделали. Быстрая работа - это изменить его на «DropCreateDatabaseAlways» или просто добавить фиктивное свойство в вашу модель/удалить свойство «фиктивный». –

0

Проблема может быть с ConnectionString вы используете в вашем web.config.

Для использования CE SQL следующего

<add name="YourContext" 
    connectionString="Data Source=|DataDirectory|yourDB.sdf" 
    providerName="System.Data.SqlServerCe.4.0"/> 

Для SQL использования Экспресса следующего

<add name="YourContext" 
    connectionString="Data source=.\SQLEXPRESS;Integrated Security=True;Initial Catalog=YourDatabase;" 
    providerName="System.Data.SqlClient" /> 

Я предполагаю, что это должно заставить все работать.

Кроме того, я думаю, вы должны посмотреть на эту статью EF Code First DB Initialization Using Web.Config. Лучше инициализировать базу данных из web.config, а не из файла global.asax

+0

Привет, спасибо за ваш ответ. Я сделал это и до сих пор не люблю. Я попытался проверить строку соединения, используемую в методе Application_Start, и ее строку соединения SQl Express без набора начального каталога. Это несмотря на то, что я установил строку подключения int it web.config AND в файле app.config в библиотеке классов. Что ты думаешь? Спасибо –

1

Я хотел поделиться другой проблемой при использовании библиотеки классов для кода, сначала & наткнулся на это сообщение. У меня был мой первый код класса POCO и DataContext в проекте библиотеки, и я хотел использовать этот проект для создания первой базы данных моего кода. Я понял, что существует флаг -ProjectName, с помощью которого можно указать проект библиотеки классов, который нужно искать при создании базы данных.

add-migration -Name 'InitialCreate' -ProjectName 'MyProject.Data' 

    update-database -ProjectName 'MyProject.Data' 
+0

В консоли диспетчера пакетов «get-help enable-migration -detailed» или «get-help add-migration -detail», чтобы увидеть другие полезные флаги для ситуации, когда DBContext и Entities находятся в библиотеке классов, но строка подключения находится в другой проект – subsci

Смежные вопросы