2012-08-31 7 views
25

これは長すぎます/あいまいですが、表のキーとして列挙型を使用して特定の状況で奇妙なエラーが発生します1つ以上の多対多の関連エンティティを含む間にテーブルに対してクエリを実行します。以下の例のコードからエンティティ・フレームワークのキーとしての列挙型5多くの多数の結合でのスロー・エラー

エラーは、次のとおりです。Global.asax.csで

public enum DietIs { 
    None, 
    Kosher, 
    Paleo, 
    Vegetarian 
} 

public class Diet { 

    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.None)] 
    public DietIs DietIs { get; set; } 

    public string Description { get; set; } 
    public virtual ICollection<Recipe> Recipes { get; set; } 
    public virtual ICollection<Menu> Menus { get; set; } 
} 

public class Recipe { 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public virtual ICollection<Diet> Diets { get; set; } 
} 

public class Menu { 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public virtual ICollection<Diet> Diets { get; set; } 
} 

public class EnumTestContextInit : DropCreateDatabaseAlways<EnumTestContext> {} 

public class EnumTestContext : DbContext { 
    public DbSet<Diet> Diets { get; set; } 
    public DbSet<Menu> Menus { get; set; } 
    public DbSet<Recipe> Recipes { get; set; } 

    public EnumTestContext() : base("EnumTestContext") { 
     Configuration.LazyLoadingEnabled = false; 
     Configuration.ProxyCreationEnabled = false; 
    } 
} 

:.NET 4.5 Webプロジェクトで

The type of the key field 'DietIs' is expected to be 'MvcApplication8.Models.DietIs', but the value provided is actually of type 'System.Int32'. 

、私は次のエンティティの構成を有しています私は、データベース初期化ファイル:次に

Database.SetInitializer(new EnumTestContextInit()); 
     using (var context = new EnumTestContext()) { 

      var noDiet = new Diet { DietIs = DietIs.None, Description = "Whatever you want" }; 
      var paleoDiet = new Diet { DietIs = DietIs.Paleo, Description = "Like paleolithic peoples" }; 
      var vegDiet = new Diet { DietIs = DietIs.Vegetarian, Description = "No meat" }; 

      context.Menus.Add(new Menu { Name = "Cheese burger with Fries Menu", Diets = new List<Diet> { noDiet } }); 
      context.Menus.Add(new Menu { Name = "Mammoth Steak Tartar with Nuts Menu", Diets = new List<Diet> { paleoDiet, noDiet } }); 
      context.Menus.Add(new Menu { Name = "Soy Cheese Pizza Menu", Diets = new List<Diet> { vegDiet, noDiet } }); 

      context.Recipes.Add(new Recipe {Name = "Cheese burger", Diets = new List<Diet> {noDiet}}); 
      context.Recipes.Add(new Recipe { Name = "Mammoth Steak Tartar", Diets = new List<Diet> { paleoDiet, noDiet} }); 
      context.Recipes.Add(new Recipe { Name = "Cheese Pizza", Diets = new List<Diet> { vegDiet, noDiet } }); 

      context.SaveChanges(); 
     } 

は、私は、データベースに対してクエリを実行しようとすると:

var context = new EnumTestContext(); 

     var dietsWithMenusAndRecipes = context.Diets 
        .Include(e => e.Menus) 
        .Include(e => e.Recipes) 
        .ToList(); 

私が1つのインクルードを使用する他のクエリは、予想されるデータを問題なくロードします。上のクエリは、2つのインクルードで上記のエラーをスローします。データベースでは、自動生成された結合テーブル(MenuDietsとRecipeDiets)が表示され、すべてのデータが正しいように見えます。前述の例のように、データに対してクエリを実行できますが、エラーをスローせずに複数の関連エンティティを含めることはできません。私はただ一つには、使用する最後のクエリを変更した場合

、私は問題なく、他のテーブルをロードすることができます

 var dietsWithMenusAndRecipes = context.Diets 
       .Include(e => e.Menus).ToList(); 

     foreach (var item in dietsWithMenusAndRecipes) { 
      context.Entry(item).Collection(e => e.Recipes).Load(); 
      var rec = item.Recipes; 
     } 

さらに - 私はテーブルを制限したいと、これは私のユースケースを満たしていないにもかかわらず私は探検

public int Id { get; set; } 
    public DietIs DietIs { get; set; } 

もう1つの可能な解決策を: - ちょうど列挙値とユニークな制約がEFでサポートされていないと、私はむしろ、列挙型のキーよりも、個別のIDキーを使用するために国会のエンティティクラスを変更した場合、これは動作します明示的に結合テーブルを作成することでした(MenuDiet sおよびRecipeDiets)を使用して、結合プロパティーキーが列挙型として型指定されたが、これでも上記のエラーが返されました。

本当にそれがチョークを引き起こしている複数のインクルードのようです。私はモデルの設定で何か間違っているかどうかについての任意のアイデア?クエリ自体は? Entity Frameworkのバグ?

+0

なぜPKのダイエットはダイエットのタイプですか?ダイエットは相互参照表ではありませんか? – zsong

+0

まあ、この例では、特定のダイエットに関する情報を追加したいと思います。ビーガンを説明し、グルテンフリーなどを記述します。また、コードで使用する列挙型の値に可能な値を制限したいintから前後にキャストする必要はありません。 –

+0

しかし、そのDietオブジェクトのPKはちょうど普通の整数でなければなりません。 FluentAPIを使用して外部キーの関係を定義したと仮定します。 – zsong

答えて

5

.NETのenumがクラスタイプであるという問題があるようです。 this pageから:

列挙の基本クラスを提供します。

そして、この発言:

列挙は、基になる型 任意の整数型である名前付き定数のセットです。基になる型が明示的に宣言されていない場合、Int32 が使用されます。列挙型は、.NET フレームワークのすべての列挙型の基本クラスです。

はい、それはタイプ整数型ですが、あなたが宣言ヨールキーの定数のセットを定義します。

public DietIs DietIs { get; set; } 

あなたの鍵は、実際にクラス型でない整数型です。積分型の値を比較または割り当てるときにキャストする必要があります。ページには、変換については、この例を提供します。

あなたが列挙体と(Visual Basicでは)または変換(C#で)キャスト演算子を使用して、その基礎となるタイプ の間で変換することができます。 次の例では、ケーシングまたは変換演算子を使用して、 の整数から列挙値への変換と 列挙値から整数への変換を実行します。

public enum ArrivalStatus { Late=-1, OnTime=0, Early=1 }; 


int value3 = 2; 
ArrivalStatus status3 = (ArrivalStatus) value3; 
int value4 = (int) status3; 
関連する問題