web-dev-qa-db-ja.com

ASP MVC FrameworkとEntity Frameworkをコードファーストアプローチでモデル化する方法は?

ユーザーテーブル、クラス、承認、認証に関してMVCフレームワークが生成するものを繰り返したり上書きしたりせずに、コードにユーザーデータ(名前、パスワード...)を含める必要がある場合、エンティティフレームワークでコードファーストアプローチをどのように設計しますか

簡単な例として、ユーザープロジェクトを管理するアプリケーションがある場合、モデルには次のクラスが含まれ、次の関係があります。

- One user may be assigned one or MANY projects
- One project may be assigned to one or MANY users

(多対多のERD関係の性質を示すためだけに)

class User{
    //implementation of the class members and 
    // navigation properties to alow Entity Framework to create the DB tables
}

class Project{
    //implementation of the class members and 
    // navigation properties to alow Entity Framework to create the DB tables
}

今私が直面している問題は、EFおよびASP= .net MVCフレームワークがユーザーテーブル、プロファイル、およびロールエンティティの作成を処理することです...

MVCによって作成された残りのテーブルとの自動(従来の)関係を示す方法でクラスを設計できるかどうかはわかりません。

カスタム認証クラスを作成してこれを行う必要がある場合、その方法を説明していただけますか?同じ問題について多くの記事を見つけましたが、プロジェクトクラスとMVCで作成されたクラス/テーブルの関係を指摘していないため、さらに、開発者がMVCを使用することを選択した場合、2つのデータコンテキストが作成されます。両方のテーブルを1つのSQLサーバーカタログにマージします。

4
joe

私があなたの質問を正しく読んでいるなら、あなたが探しているのはSimpleMembershipです。

これが SimpleMembershipの説明 ;です。セクションからEasy to with [sic] Entity Framework Code First

SimpleMembership ...を使用すると、(changed]任意のテーブルをユーザーストアとして使用できます。つまり、ユーザープロファイル情報を管理していて、好きな方法でアクセスできます。

したがって、独自のUserクラスを定義して、追加のユーザーデータと関係を保持できます。例:

[Table("UserProfile")]
public class UserProfile
{
    // required fields:
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int      UserId { get; set; }
    public string   UserName { get; set; }

    // your extra fields:
    public List<Project> Projects { get; set; }
    // more here...
}

そして通常の組み込みのMembership要素は、ログイン、パスワード、およびその他すべての舞台裏を処理するために使用されます。

それを統合するためにやるべきことはもう少しありますが、私がそれを使用したとき、それはそれほど悪くはありませんでした。

これはMVC4以降で機能することに注意してください。


コメントで尋ねられた質問に対処するために編集します。

私のコードを見てわかることから(プロジェクトに取り組んでからしばらく経ちましたが、それが最初のMVCプロジェクトであり、それ以来他のプロジェクトが頭を悩ませているので、状況は少しあいまいです)。

DbContextクラスから継承した独自のコンテキストを作成してしまったようです( (このチュートリアル で説明されています)。すべてのアプリケーションデータが含まれています)。例えば。:

public class MyContext : DbContext
{
    public MyContext()
        : base("DefaultConnection")
    {

    }

    public DbSet<UserProfile> UserProfiles { get; set; }
    public DbSet<Projects> Projects { get; set; }
    // more here
}

(IIRC、DbContextタイプから継承することにより、すべての組み込みメンバーシップ情報を取得します。)

次に、アプリの残りの部分をこのチュートリアルを使用するように構成する必要がありました(チュートリアルで指定)。 (すべてのコントローラーが派生コンテキストのインスタンスを作成しますが、これは依存関係注入を使用してセットアップすることもできます。)

データベース接続はデフォルトでInitializeSimpleMembershipAttributeで初期化されているようです-この属性はすべてのコントローラーに適用されます。

この設定で この質問 に記載されている問題に遭遇したので、それを修正するために、承認された回答のアドバイスに従い、データベース接続の初期化コードを中心点(Global.asax.cs)に移動しましたこれは、Webアプリの起動時に一度だけ実行されました。

これ以上の詳細を思い出せないのではないかと思います。これを機能させるには、おそらくもう少し調査(そしておそらくトラブルシューティング)を行う必要がありますが、それによって何を見るべきかについて適切な考えが得られるはずです。ために。

asp.net で多くのチュートリアルを読んだので、まだ読んでいない場合は、そのサイトをチェックしてください。

2
paul

これを実現する方法を次に示します。

既存のAsp.Net Mvcアカウントテーブルを利用する方法に加えて、要件に加えて、テーブルにさらに追加する方法を説明します。

まず、以下のパッケージをインストールする必要があります。

Install-Package Microsoft.AspNet.Identity
  Install-Package Microsoft.AspNet.Identity.EntityFramework

今、あなたは次のようにさらに行う必要があります。

まず、Asp.Net Identityは、次のプロパティを含むIdentityUserテーブルを提供します

Id、UserName、PasswordHash、SecurityStamp、Discriminator

クラスを作成してIdentityUserから継承することで、さらにプロパティを追加したいとします。

ここに例を示します。私はそれをクライアントと呼びます。

public class Client:IdentityUser
{

      //Suppose I want to add Further Properties to to my IdentityUser 
      //table provided by Asp.Net by default.
      //suppose i want Email,Date Birth.

   [Required]
   [Display(Name = "Email")]
   public string Email { get; set; }

   [Required]
   [Display(Name = "BirthDate")]
   public DateTime BirthDate { get; set; }

}


Now Create Your Model classes Lets say in my case One User can have many Projects.



 public class Project
  {


 //Now all your properties will go here
   // plus now you can connect projects to IdentityUser
   //by using Client class which is inherited from IdentityUser.

        public virtual Client Client{get; set;}

   }

あなたのさらなるモデルクラスはここに行きます。

public class  SecondModelClass
   {

   }


Now Go to your context rather than inheriting it from DbContext you can inherit it from  IdentityDbContext   here is sample code below.

//Notice I am passing it Client class which was inherited from IdentityUser

public class YourContextName:IdentityDbContext<Client>
{


    public YourContextName():base("connectionStringName")
    {


    }


    public class IdentityUserLoginConfiguration :      EntityTypeConfiguration<IdentityUserLogin>
    {
        public IdentityUserLoginConfiguration()
        {
            HasKey(iul => iul.UserId);
        }
    }


    public class IdentityUserRoleConfiguration : EntityTypeConfiguration<IdentityUserRole>
    {
        public IdentityUserRoleConfiguration()
        {
            HasKey(iur => iur.RoleId);
        }

    }



    public DbSet<Project> Projects { get; set; }

    public DbSet<ModelClass2> AnyName { get; set; }

    public DbSet<ModelClass3> MoreClassesName { get; set; }




    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new IdentityUserLoginConfiguration());
        modelBuilder.Configurations.Add(new IdentityUserRoleConfiguration());
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

    }





}

これで、AccountController全体で、IdentityUserから継承したClientクラスを渡す必要があります。

public class AccountController : Controller
{
    public AccountController()
        : this(new UserManager<Client>(new UserStore<Client>(new Context.YourContextName())))
    {
    }

    public AccountController(UserManager<Client> userManager)
    {
        UserManager = userManager;
    }

    public UserManager<Client> UserManager { get; private set; }


  //Further Code Will go below here........................
  //

}

このソリューションは、Asp.Net Identityによって提供されるすべてに加えて、カスタマイズも利用します。

乾杯。

2