web-dev-qa-db-ja.com

Entity Framework Code-First-このEntityTypeのキーを定義します

こんにちは、私のプロジェクトの1つでEF Code Firstをテストする予定です。これが実際に欲しいものです。 3つのテーブルがあり、構造は次のとおりです。

public partial class App_user
    {
        public int id { get; set; }
        public string name { get; set; }
        public string email_address { get; set; }
        public string password { get; set; }
        public int user_type { get; set; }
        public List<Role> Roles { get; set; }
    }

public partial class Role
    {
        public int id { get; set; }
        public string name { get; set; }
    }
public partial class User_role
    {
        public int user_id { get; set; }
        public int role_id { get; set; }
        public virtual Role Role { get; set; }
        public virtual App_user App_user { get; set; }
    }

3番目の表には、主キーはありません。そのため、実行中にエラーが発生します。エラーメッセージは次のとおりです-

System.Data.Edm.EdmEntityType::EntityType 'User_role'にはキーが定義されていません。このEntityTypeのキーを定義します。 System.Data.Edm.EdmEntitySet:EntityType:EntitySet User_rolesは、キーが定義されていないUser_roleタイプに基づいています。

なぜそれが起こっているのですか?これに対する解決策はありますか?

26
Mukesh

ユーザーとロールの間の多対多の関係をモデル化しようとしていると思われる場合。そのような場合、モデルは完全に間違っています。

代わりにこれを使用してください:

public partial class App_user
{
    public int id { get; set; }
    public string name { get; set; }
    public string email_address { get; set; }
    public string password { get; set; }
    public int user_type { get; set; }
    public virtual ICollection<Role> Roles { get; set; }
}

public partial class Role
{
    public int id { get; set; }
    public string name { get; set; }
    public virtual ICollection<User> Users { get; set; }
}

これにより、多対多が自動的に作成されるため、ジャンクションテーブルを気にする必要はありません。ジャンクションテーブルを公開する必要がある場合は、これを使用する必要があります。

public partial class App_user
{
    public int id { get; set; }
    public string name { get; set; }
    public string email_address { get; set; }
    public string password { get; set; }
    public int user_type { get; set; }
    public virtual ICollection<User_Role> UserRoles { get; set; }
}

public partial class Role
{
    public int id { get; set; }
    public string name { get; set; }
    public virtual ICollection<User_Role> UserRoles { get; set; }
}

public partial class User_role
{
    [Key, ForeignKey("App_user"), Column(Order = 0)]
    public int user_id { get; set; }
    [Key, ForeignKey("Role"), Column(Order = 1)]
    public int role_id { get; set; }
    public virtual Role Role { get; set; }
    public virtual App_user App_user { get; set; }
}

ジャンクションテーブルを公開することは、追加のプロパティが必要なければ意味がありません。

あなたのエラー-エンティティフレームワークの各エンティティには、プライマリキーが定義されている必要があります。

37
Ladislav Mrnka

このようにすることができます:

public partial class User_role
{
    [Key]
    public int user_id { get; set; }
    [Key]
    public int role_id { get; set; }
    public virtual Role Role { get; set; }
    public virtual App_user App_user { get; set; }
}
19
Yngve B-Nilsen

自動生成コードでADO.net Entiry Data Modelを使用したため、Modelクラスを変更したくなかったため、WebApiConfig.csを変更して、基礎となるモデルのキーを定義しました。

ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
EntitySetConfiguration<Registration> EntitySetConfiguration_Registration = builder.EntitySet<Registration>("Registration");
EntitySetConfiguration<Lead> EntitySetConfiguration_Lead = builder.EntitySet<Lead>("Lead");
EntitySetConfiguration<Session> EntitySetConfiguration_Session = builder.EntitySet<Session>("Session");
EntitySetConfiguration_Registration.EntityType.HasKey(p => p.Registration_Id);
EntitySetConfiguration_Lead.EntityType.HasKey(p => p.Lead_Id);
EntitySetConfiguration_Session.EntityType.HasKey(p => p.Session_Id);
config.Routes.MapODataRoute("odata", "odata", builder.GetEdmModel());
1
LiQuick.net

使用していることを確認してください(System.ComponentModel.DataAnnotations;を使用)

モデルのデータフィールドの上部にキーワード[Key]を追加するだけです

0
Nelson