28

ASP.NET MVC 4 を使用したことがある場合は、インターネット アプリケーションの既定で SimpleMembership プロバイダーが使用されることに気付くでしょう。これはすべて問題なく、正常に動作します。

UserProfile問題はデフォルトのデータベース生成に伴い、次のように定義された POCO があります。

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

.. 次のように生成されます。

using (var context = new UsersContext())
{
    if (!context.Database.Exists())
    {
         // Create the SimpleMembership database without Entity Framework migration schema
         ((IObjectContextAdapter)context).ObjectContext.CreateDatabase();
    }
}

これは正常に動作し、データベースは問題なく生成され、問題なく動作します。ただし、POCO を次のように変更してデータベースを削除する場合:

[Table("UserProfile")]
public class UserProfile
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }
    public string EmailAddress { get; set; }

    public string FirstName { get; set; }
    public string Surname { get; set; }

    public string Country { get; set; }

    public string CompanyName { get; set; }
}

最初の 2 列のみが生成されUserIdますEmailAddress。コード的には問題なく動作しますが(ログイン/登録の話)、明らかに他のユーザーデータは保存されていません。

ここで何か不足していますか?確かに、UserProfileオブジェクト全体に基づいてデータベースを生成する必要があります。

4

4 に答える 4

47

1 - できれば EntityFramework 5 で移行を有効にする必要があります。NuGetEnable-Migrationsパッケージ マネージャーで使用します。

2 - あなたの

WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "EmailAddress", autoCreateTables: true); 

YourMvcApp/Migrations/Configuration.cs クラスの Seed メソッドに

    protected override void Seed(UsersContext context)
    {
        WebSecurity.InitializeDatabaseConnection(
            "DefaultConnection",
            "UserProfile",
            "UserId",
            "UserName", autoCreateTables: true);

        if (!Roles.RoleExists("Administrator"))
            Roles.CreateRole("Administrator");

        if (!WebSecurity.UserExists("lelong37"))
            WebSecurity.CreateUserAndAccount(
                "lelong37",
                "password",
                new {Mobile = "+19725000000", IsSmsVerified = false});

        if (!Roles.GetRolesForUser("lelong37").Contains("Administrator"))
            Roles.AddUsersToRoles(new[] {"lelong37"}, new[] {"Administrator"});
    }

これで、EF5 が UserProfile テーブルの作成を担当します。その後、WebSecurity.InitializeDatabaseConnection を呼び出して、作成済みの UserProfile テーブルに SimpleMembershipProvider のみを登録し、SimpleMembershipProvider にどの列が UserId と UserName であるかを伝えます。また、ユーザー、ロールを追加し、Seed メソッドで 2 つをカスタム UserProfile プロパティ/フィールド (ユーザーのモバイル (番号) など) に関連付ける方法の例も示しています。

3 - パッケージ マネージャー コンソールから update-database を実行すると、EF5 はすべてのカスタム プロパティを使用してテーブルをプロビジョニングします。

追加の参照については、ソースコードを含むこの記事を参照してください: http://blog.longle.net/2012/09/25/seeding-users-and-roles-with-mvc4-simplemembershipprovider-simpleroleprovider-ef5-codefirst-and-custom -ユーザープロパティ/

于 2012-09-28T17:31:32.477 に答える
5

私はついにこれを手に入れたようですが、それはただの大きな誤解だったのかもしれません.

((IObjectContextAdapter)context).ObjectContext.CreateDatabase();結局のところ、存在しないデータベース内のすべてのテーブルを作成するか、それらが存在し、それらが異なる場合は単にそれらを更新するという、単純に行わないことを行うことを期待していました。

実際に起こることは、文字通りCREATE DATABASEステートメントを実行することです。これは、私にとってこれまでで最も役に立たないことです。本当に奇妙な環境で作業していない限り、データベースは常にオフになっているため、常に存在します (その後、テーブルの作成は決して行われません!)、実際のユーザーにアクセスを許可したくありません。とにかくデータベースを作成します。

とにかく、イニシャライザを使用してデータベースを作成し、以下のような初期化を強制することで、UserProfile(および関連するテーブル) を作成するという特定の問題を解決しました。DropCreateDatabaseIfModelChanges

public SimpleMembershipInitializer()
{
#if DEBUG
    Database.SetInitializer<DataContext>(new DropCreateDatabaseIfModelChanges<DataContext>());
#else
    Database.SetInitializer<DataContext>(null);
#endif

    try
    {
        using (var context = new DataContext())
        {
            if (!context.Database.Exists())
            {
                ((IObjectContextAdapter)context).ObjectContext.CreateDatabase();
            }
            context.Database.Initialize(true);
        }

        WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "EmailAddress", autoCreateTables: true);
    }
    catch (Exception ex)
    {
        throw new InvalidOperationException("The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.microsoft.com/fwlink/?LinkId=256588", ex);
    }
}

..これは機能し、開発には最適ですが、モデルが変更された場合、文字通りデータベースを削除して最初から再作成するため、実際にはほとんど役に立ちません。私にとって、これにより、コードファーストのプラクティス全体がデフォルトの形式ではほとんど役に立たなくなり、おそらくDBからのedmx生成に戻ることになります。

UserProfileまだ作成中のテーブルの背後にある「謎」は、テーブルWebSecurity.InitializeDatabaseConnectionに渡すフィールドに基づいてテーブルが存在しない場合にテーブルを初期化することです。これが、 のEmailAddress代わりに が作成された理由UserNameです。

于 2012-09-23T22:47:51.087 に答える
2

私は同じ問題を抱えていました。SimpleMembershipInitializerの「CreateDatabase」の直前に移行を実行するためのコードをに追加しました。

これで問題は解決しましたが、公開プロファイルの設定に関係なく、移行がAzureに適用されるようになると思います。

  private class SimpleMembershipInitializer
    {
        public SimpleMembershipInitializer()
        {
            Database.SetInitializer<WomContext>(null);

            // forcing the application of the migrations so the users table is modified before
            // the code below tries to create it. 
            var migrations = new MigrateDatabaseToLatestVersion<WomContext, Wom.Migrations.Configuration>();
            var context = new WomContext(); 
            migrations.InitializeDatabase(context); 

            try
            {....
于 2012-10-21T23:39:29.637 に答える