2011-12-25 11 views
4

今朝私はEF4コードに手を入れ始めました。別のクラスライブラリにPOCO、データコンテキスト、Initializerクラスを作成しました。これは通常のボイラープレートタイプのコードだと思います。 MVC3アプリケーションでクラスを参照し、Global.asaxで初期化子を設定します。アプリケーションを実行すると、次のような問題が発生します。
1.データベースが作成されていません初期化された値にアクセスしようとすると、明らかにデータがないため、エラーが発生します。エンティティフレームワークコードクラスライブラリの最初

誰が おかげ
(私はこれを学ぶ私の全体のクリスマスの一日を過ごしたと私はまだそれが:(仕事を得ることができない場合は恥だろう)THIものが動作するように取得する方法についてのポインタで私を助けてくださいpsの私は、ブレークポイントを挿入しようと、私は、アプリの初期化方法を打つが、それは私もそこにブレークポイントを追加していても初期化子における種子方法を打つことはありません!!
感謝。
初期化子クラス

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のアプリケーションの初期化方法

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

ユーレカが最終的に!
解決策を探しているうちに、私はこのポストに出くわしましたEntity Framework Database.SetInitializer simply not working
解決策を適用すると、私のデータベースが期待どおりに起動するように強制されましたが、シードコードを実行しているときにNULLポインタ例外がスローされました。調べているうちに、ContextクラスからDBSetコレクションを参照しようとすると、同じ例外が発生することがわかりました。検査は、さらに私の代わりに

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

を使用しての私は任意の暗黙オブジェクトの初期化、ひいてはnullポインタ例外を取得していないことを意味

public DbSet<MobileTerminal> MobileTerminals; 

を使用していたことに気づきました。私は強制初期化コードを削除し、アプリケーションを再度実行しました。今回は、実際にデータコンテキストを照会したページにアクセスするまでシードコードが実行されず、完全に実行されました。明らかに、遅延ロードのために、初期化コードは実際に必要とされるまで、すなわちデータコンテキストがアプリケーションで最初に照会されるまで実行されないことは明らかである。

これは、今後同じ問題が発生した場合に役立ちます。

+0

少し話題にはなりませんが、デバッグするのに楽しいのは、 'DropCreateDatabaseAlways'(* face-palm * moment)の代わりに' DropCreateDatabaseIfModelChanges'で上記のコードを使用しています。この問題についてこのページに来ても、上記の解決策がうまくいかない場合は、これをしていないことを確認してください。素早く回避するには、 'DropCreateDatabaseAlways'に変更するか、モデルにダミープロパティを追加するかダミープロパティを削除するだけです。 –

0

問題は、あなたのweb.configファイルで使用しているのConnectionStringであるかもしれません。

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

次のSQL Expressの使用については

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

を次のSQL CE用の

は、私は、これは物事を動作させる必要がありますね。

また、私はこの記事EF Code First DB Initialization Using Web.Configをご覧ください。 global.asaxファイルではなく、web.configからデータベースを初期化する方が良いです。

+0

こんにちは、あなたの応答のおかげで。私はそれをしても、まだ愛はありません。 Application_Startメソッドで使用されている接続文字列と、初期カタログが設定されていないSQl Express接続文字列を確認しようとしました。これは、web.configの接続文字列intをクラスライブラリのapp.configファイルに設定しているにもかかわらずです。あなたの考えは?ありがとう –

1

最初にコード用のクラスライブラリを使用するときに別の問題を共有したいと思っていました&がこの記事に遭遇しました。私は自分のコードを最初のPOCOとDataContextクラスをライブラリプロジェクトにも持っていて、このプロジェクトを使って自分のコードの最初のデータベースを作成したかったのです。私は、データベースを作成するときに探すクラスライブラリプロジェクトを指定できる-ProjectNameフラグがあることを理解しました。

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

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

DBContextとEntitiesがクラスライブラリにあるが接続文字列が入っている状況のために、パッケージマネージャコンソールの 'get-help enable-migrations -detailed'または' get-help add-migration -detail'別のプロジェクト – subsci