88

新しい Asp.net ID を Database First と EDMX で使用することはできますか? それとも最初にコードだけですか?

これが私がしたことです:

1) 新しい MVC5 プロジェクトを作成し、新しい ID でデータベースに新しいユーザー テーブルとロール テーブルを作成しました。

2) 次に、Database First EDMX ファイルを開き、関連する他のテーブルがあるため、新しい Identity Users テーブルにドラッグしました。

3) EDMX を保存すると、Database First POCO ジェネレーターがユーザー クラスを自動作成します。ただし、UserManager と RoleManager は、新しい Identity 名前空間 (Microsoft.AspNet.Identity.IUser) から継承する User クラスを想定しているため、POCO User クラスを使用しても機能しません。

考えられる解決策は、POCO Generation Classes を編集して、User クラスが IUser から継承するようにすることだと思いますか?

それとも、ASP.NET Identity は Code First Design とのみ互換性がありますか?

++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++

更新: 以下の Anders Abel の提案に従って、これが私がしたことです。それはうまくいきますが、もっとエレガントな解決策があるかどうか疑問に思っています。

1) 自動生成されたエンティティと同じ名前空間内に部分クラスを作成して、エンティティ User クラスを拡張しました。

namespace MVC5.DBFirst.Entity
{
    public partial class AspNetUser : IdentityUser
    {
    }
}

2) DBContext ではなく IdentityDBContext から継承するように DataContext を変更しました。EDMX を更新して DBContext および Entity クラスを再生成するたびに、これをこれに戻す必要があることに注意してください。

 public partial class MVC5Test_DBEntities : IdentityDbContext<AspNetUser>  //DbContext

3) 自動生成された User エンティティ クラス内で、override キーワードを次の 4 つのフィールドに追加するか、これらのフィールドをコメント アウトする必要があります。これらのフィールドは IdentityUser から継承されているためです (ステップ 1)。EDMX を更新して DBContext および Entity クラスを再生成するたびに、これをこれに戻す必要があることに注意してください。

    override public string Id { get; set; }
    override public string UserName { get; set; }
    override public string PasswordHash { get; set; }
    override public string SecurityStamp { get; set; }
4

9 に答える 9

16

POCO および Database First で ID システムを使用できるはずですが、いくつか調整する必要があります。

  1. POCO 生成用の .tt ファイルを更新して、エンティティ クラスを作成しますpartial。これにより、別のファイルで追加の実装を提供できるようになります。
  2. User別のファイルでクラスの部分実装を作成する

 

partial User : IUser
{
}

これによりUser、実際に生成されたファイルに触れることなく、クラスに適切なインターフェイスを実装させることができます (生成されたファイルを編集することは常に悪い考えです)。

于 2013-11-12T21:30:09.563 に答える
13

私の手順は非常に似ていますが、共有したいと思いました。

1) 新しい MVC5 プロジェクトを作成する

2) 新しい Model.edmx を作成します。新しいデータベースで、テーブルがない場合でも。

3) web.config を編集し、この生成された接続文字列を置き換えます。

<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-SSFInventory-20140521115734.mdf;Initial Catalog=aspnet-SSFInventory-20140521115734;Integrated Security=True" providerName="System.Data.SqlClient" />

この接続文字列で:

<add name="DefaultConnection" connectionString="Data Source=.\SQLExpress;database=SSFInventory;integrated security=true;" providerName="System.Data.SqlClient" />

その後、アプリケーションをビルドして実行します。ユーザーを登録すると、テーブルが作成されます。

于 2014-05-21T17:48:36.130 に答える
8

IdentityUserUserStore認証のために によって使用されるコード ファースト オブジェクトであるため、ここでは価値がありません。独自のオブジェクトを定義した後、クラスで使用されるUserを実装する部分クラスを実装しました。s を文字列ではなくしたかったので、UserID の toString() を返すだけです。同様に、私は大文字にしないようにしたかったのです。IUserUserManagerIdintnUsername

public partial class User : IUser
{

    public string Id
    {
        get { return this.UserID.ToString(); }
    }

    public string UserName
    {
        get
        {
            return this.Username;
        }
        set
        {
            this.Username = value;
        }
    }
}

あなたは決して必要ありませんIUser。によって使用される単なるインターフェイスUserManagerです。したがって、別の「IUser」を定義したい場合は、独自の実装を使用するようにこのクラスを書き直す必要があります。

public class UserManager<TUser> : IDisposable where TUser: IUser

UserStoreここで、ユーザー、クレーム、ロールなどのすべてのストレージを処理する独自のものを作成します。コードが最初に実行するすべてのインターフェイスを実装し、「ユーザー」がエンティティ オブジェクトである場所UserStoreに変更where TUser : IdentityUserします。where TUser : User

public class MyUserStore<TUser> : IUserLoginStore<TUser>, IUserClaimStore<TUser>, IUserRoleStore<TUser>, IUserPasswordStore<TUser>, IUserSecurityStampStore<TUser>, IUserStore<TUser>, IDisposable where TUser : User
{
    private readonly MyAppEntities _context;
    public MyUserStore(MyAppEntities dbContext)
    { 
        _context = dbContext; 
    }

    //Interface definitions
}

インターフェイスの実装のいくつかの例を次に示します。

async Task IUserStore<TUser>.CreateAsync(TUser user)
{
    user.CreatedDate = DateTime.Now;
    _context.Users.Add(user);
    await _context.SaveChangesAsync();
}

async Task IUserStore<TUser>.DeleteAsync(TUser user)
{
    _context.Users.Remove(user);
    await _context.SaveChangesAsync();
}

MVC 5 テンプレートを使用して、次のAccountControllerように変更しました。

public AccountController()
        : this(new UserManager<User>(new MyUserStore<User>(new MyAppEntities())))
{
}

ログインすると、独自のテーブルで動作するはずです。

于 2014-01-14T20:02:27.663 に答える
3

GitHub でこのプロジェクトを見てみましょう: https://github.com/KriaSoft/AspNet.Identity

含まれるもの:

  • ASP.NET Identity 2.0 用の SQL データベース プロジェクト テンプレート
  • Entity Framework データベース ファースト プロバイダー
  • ソースコードとサンプル

ここに画像の説明を入力

参照: ADO.NET ID 用の Database-First プロバイダーを作成する方法

于 2014-04-13T08:59:54.180 に答える
3

良い質問。

私はデータベースファーストの人です。コードファーストのパラダイムは、私には緩いように思えます。また、「移行」はエラーが発生しやすいようです。

aspnet ID スキーマをカスタマイズし、移行に煩わされないようにしたかったのです。私は、Visual Studio データベース プロジェクト (sqlpackage、data-dude) に精通しており、それがスキーマのアップグレードでどのようにうまく機能するかを熟知しています。

私の単純な解決策は次のとおりです。

1) aspnet ID スキーマを反映するデータベース プロジェクトを作成する 2) このプロジェクトの出力 (.dacpac) をプロジェクト リソースとして使用する 3) 必要に応じて .dacpac をデプロイする

MVC5の場合、ApplicationDbContextクラスを変更するとこれがうまくいくようです...

1) 実施するIDatabaseInitializer

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>, IDatabaseInitializer<ApplicationDbContext> { ... }

2) コンストラクターで、このクラスがデータベースの初期化を実装することを通知します。

Database.SetInitializer<ApplicationDbContext>(this);

3) 実装InitializeDatabase:

ここでは、DacFX を使用して .dacpac をデプロイすることにしました。

    void IDatabaseInitializer<ApplicationDbContext>.InitializeDatabase(ApplicationDbContext context)
    {
        using (var ms = new MemoryStream(Resources.Binaries.MainSchema))
        {
            using (var package = DacPackage.Load(ms, DacSchemaModelStorageType.Memory))
            {
                DacServices services = new DacServices(Database.Connection.ConnectionString);
                var options = new DacDeployOptions
                {
                    VerifyDeployment = true,
                    BackupDatabaseBeforeChanges = true,
                    BlockOnPossibleDataLoss = false,
                    CreateNewDatabase = false,
                    DropIndexesNotInSource = true,
                    IgnoreComments = true,

                };
                services.Deploy(package, Database.Connection.Database, true, options);
            }
        }
    }
于 2015-09-17T04:47:06.483 に答える
2

私はこれに数時間を費やし、最終的に解決策を見つけました。これは私のブログで共有しています基本的に、 stinkの回答に記載されているすべてを実行する必要がありますが、さらに 1 つ追加する必要があります。アプリケーション エンティティに使用される Entity Framework 接続文字列の上に、Identity Framework に特定の SQL クライアント接続文字列があることを確認することです。

要約すると、アプリケーションは、Identity Framework に接続文字列を使用し、アプリケーション エンティティに別の接続文字列を使用します。各接続文字列は異なる型です。完全なチュートリアルについては、私のブログ投稿をお読みください。

于 2014-05-20T19:03:01.583 に答える
1

モデル クラスを保持する Entity Model DLL プロジェクトがあります。また、すべてのデータベース スクリプトを含むデータベース プロジェクトも保持します。私のアプローチは次のとおりでした

1) 最初にデータベースを使用して EDMX を持つ独自のプロジェクトを作成します。

2)データベース内のテーブルのスクリプトを作成します。ローカルDB(データ接続)に接続されたVS2013を使用し、スクリプトをデータベースプロジェクトにコピーし、カスタム列を追加します.BirthDate [DATE] not nullなど

3) データベースをデプロイする

4) モデル (EDMX) プロジェクトを更新する モデル プロジェクトに追加します。

5) カスタム列をアプリケーション クラスに追加します。

public class ApplicationUser : IdentityUser
{
    public DateTime BirthDate { get; set; }
}

MVC プロジェクト AccountController で、以下を追加しました。

ID プロバイダーは、SQL 接続文字列が機能することを望んでおり、データベースの接続文字列を 1 つだけ保持し、EF 接続文字列からプロバイダー文字列を抽出します。

public AccountController()
{
   var connection = ConfigurationManager.ConnectionStrings["Entities"];
   var entityConnectionString = new EntityConnectionStringBuilder(connection.ConnectionString);
        UserManager =
            new UserManager<ApplicationUser>(
                new UserStore<ApplicationUser>(
                    new ApplicationDbContext(entityConnectionString.ProviderConnectionString)));
}
于 2014-04-06T15:45:13.677 に答える