2012-04-21 4 views
1

EF 4.0.0からEF 4.3.1にアップグレードしました。 最新のリリースに更新されたWindows XP上でVisual Studio 2010 Ultimateを使用しており、適用されるすべてのWindowsアップデート/パッチが適用されています。私が使用しているデータベースエンジンはSQL Server 2008 R2 Developers Editionです。 次のコードは、EF 4.0.0では完全に機能しますが、EF 4.3.1では機能しません。EF 4.0.0から4.3.1へのアップグレードで奇妙なエラーが発生しました

public class ItemBase 
{ 
    public DateTime Created { get; set; } 
    public int CreatedByUserID { get; set; } 
    public DateTime LastModified { get; set; } 
    public int LastModifiedByUserID { get; set; } 

    public User CreatedBy { get; set; } 
    public User LastModifiedBy { get; set; } 

    public ItemBase() 
    { 
     CreatedByUserID = -1; 
     LastModifiedByUserID = -1; 
     CreatedBy = null; 
     LastModifiedBy = null; 
    } 
} 


public class User : ItemBase 
{ 
    public int UserID { get; set; } 
    public string LoginName { get; set; } 
    public string Password { get; set; } 
    public string EmailAddress { get; set; } 
    public string Firstname { get; set; } 
    public string Lastname { get; set; } 
    public string DisplayName { get; set; } 

    public User() : base() 
    { 
     UserID = -1; 
     LoginName = String.Empty; 
     Password = String.Empty; 
     EmailAddress = String.Empty; 
     Firstname = String.Empty; 
     Lastname = String.Empty; 
     DisplayName = String.Empty; 
    } 
} 


protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder) 
{ 
    base.OnModelCreating(modelBuilder); 
    modelBuilder.Entity<User>().Property(u => u.UserID).HasDatabaseGenerationOption(DatabaseGenerationOption.Identity); 
} 

変更されたのは、私が使用しているEntity Frameworkのバージョンだけです。 私は参照などをチェックして、すべてが期待通りです。

上記のコードからわかるように、UserクラスはItemBaseを継承し、ItemBaseはUserインスタンスへの参照を継承しています。基本Userテーブルには、UserクラスとItemBaseクラスのすべてのプロパティが含まれます(public User CreatedBy {get; set;}およびpublic User LastModifiedBy {get; set;}) このコードを4.0で実行します。 0すべてが期待どおりに機能し、単一の問題や問題はありません。

しかし、私は(私が使用しているデータベースを含む他の何かに一切の変更を伴わない)4.3.1の下で同じコードを実行したときに、私は次のエラーを取得する:

元本を決定することができません。この関連付けの主な終点は、流暢なAPIまたはデータアノテーションのどちらかの関係を使用して明示的に設定する必要があります。 "

そこで、次の2行をOnModelCreatingメソッド:

modelBuilder.Entity<User>().HasRequired(u => u.CreatedBy).WithMany().HasForeignKey(k => k.CreatedByUserID); 
modelBuilder.Entity<User>().HasRequired(u => u.LastModifiedBy).WithMany().HasForeignKey(k => k.LastModifiedByUserID); 

私は、これらの奇妙なエラーを取得:

プロバイダはProviderManifestToken文字列を返しませんでした。 "

" SQL Serverへの接続を確立する際に、ネットワーク関連またはインスタンス固有のエラーが発生しました。サーバーが見つからなかったか、アクセスできませんでした。インスタンス名が正しいこと、およびSQL Serverがリモート接続を許可するように構成されていることを確認します。 (プロバイダ:SQLネットワークインターフェイス、エラー:26 - エラー位置決めサーバー/インスタンスの指定)

私はまた、出力ウィンドウにロードし、これらのエラーの負荷を気づい: 」型「システムの最初のチャンス例外を.Data.SqlClient.SqlException 'System.Data.dllで発生しました "

しかし、これらのエラーはデータベースが正常であり、利用可能で、接続文字列も完璧であるため、赤字のビットであるようです私がOnModelCreatingメソッドの変更を元に戻すと、元のエラーが再び発生するため、実際に発生している問題の原因を実際に反映しているとは思わない再。

だから、このすべてに基づいて、私は次のような結論に来る:

  1. Entity Frameworkのバージョン4.3.1のバグがありますか?
  2. 私のコードが4.0で動作したという事実。0を余分な2行なしでOnModelCreatingメソッドの はおそらく今度は4.3.1で行われている4.0.0で作られた のチェックではなかったでしょうか?
  3. 設定/コードに余分なものを追加する必要があります。あるいは、 が4.3.1でこの作業をやり直すために他に何か不足していますか?

誰でも私のためにこれにいくつかの光を当てることができますか?それは私のナットを運転! これにお時間をいただきありがとうございます。 親切にしてください スティーブ

+0

私はあなたの設定する外部キーを-1とすると、EF内部の制約に失敗する可能性があると考えていますか? –

+0

箱にはどのようなデータベースがありますか?それはSqlExpressか通常のSqlServerですか?あなたの設定に接続文字列を持っているのか、EFを使って接続文字列を思いついているのですか?私はEF 4.3.1がlocaldbに接続しようとしているのか疑問に思っています。 – Pawel

答えて

2

EF 4.1のプレリリース版を使用しているようです。おそらくCTP4またはCTP5。これは明らかである理由:

    ModelBuilderのは、4.1 RTM
  • DatabaseGenerationOptionが
  • あなたがEF 4.1の前に導入された見ている例外はRTM'ed

DatabaseGeneratedOptionに改称前DbModelBuilderに名前が変更されました

  • これを考えると、あなたが使っていたプレリリース版では、どのモデルが作成されているのかを100%確信しているわけではありません。 4.1以上では、2つのナビゲーションプロパティが相互の逆として検出され、コードファーストはユーザーとユーザーの間に1対1の関係を確立しようとします。 Code Firstは、この関係のプリンシパルを決定することはできません。

    しかし、あなたのモデルを見ると、これはあなたがとにかく欲しいものではないことは明らかです。あなたがCreatedByとLastModifiedByの2つの1:*単方向ナビゲーション小道具を2つ必要とする可能性は非常に高いようです。これがOnModelCreatingコールの設定です。

    クラスの名前を4.1/4.3に変更し、コードをOnModelCreatingに追加すると、コードはEF 4.3.1で問題なく動作します。

    接続ができないということは、接続文字列が正しいと言います。この場合、EFが見つからない場合があります。それがあなたのapp.configにあると仮定すると、その名前をDbContextコンストラクタに渡す必要があります。たとえば、次のようになります。

    public class MyContext : DbContext 
    { 
        public MyContext() 
        : base("name=MyConnectionStringName") 
        { 
        } 
    } 
    

    接続文字列を他の方法で使用している場合は、その詳細が必要です。

  • 関連する問題