2017-03-14 4 views
3

完全に異なる2つのユーザーセットを1つのDBに格納しようとしています2つの異なるアプリケーション。両方のユーザクラスには別々の権限、クレーム、ログインなどが必要です。多重度はロール1で無効です* OR EF変わった移行コードOR別々の2つの異なるユーザーセットを1つのDBに格納する方法

ここでのIdentityFrameworkの目標は、基本的な認証と認証メカニズムを提供することです。使用

パッケージ:

EntityFramework v6.1.3 
Microsoft.AspNet.Identity.Core v2.2.1 
Microsoft.AspNet.Identity.EntityFramework v2.2.1 
MySql.Data v6.8.7 
MySql.Data.Entity v6.8.7 

は、私の知る限りIdentityDbContextを使用して、そうするオプションはありませんので、私は自分でそれをするつもり。 IdentityDbContextのソースを見ると、マッピングと検証の2つの主要な機能があります。また、ID V1スキーマが使用されているかどうかをチェックしますが、私の場合はそうではありません。

私はIdentityDbContextの使用を取り除くために私のコードをリファクタリングしようとします。私のアイデンティティモデルは以下のとおりです。

public class ReproUser : IdentityUser<int, ReproLogin, ReproUserRole, ReproClaim> { } 
public class ReproClaim : IdentityUserClaim<int> { } 
public class ReproUserRole : IdentityUserRole<int> { } 
public class ReproLogin : IdentityUserLogin<int> { } 
public class ReproRole : IdentityRole<int, ReproUserRole> { } 

とマッピングはだから私は(テーブル、ネーミング・など)の詳細を除いてIdentityDbContextマッピングを模倣

internal class ReproUserRoleMap : EntityTypeConfiguration<ReproUserRole> 
{ 
    public ReproUserRoleMap() 
    { 
     HasKey(r => new { r.UserId, r.RoleId }); 

     ToTable(typeof(ReproUserRole).Name + "sBridge"); 

     Property(t => t.UserId).HasColumnName("UserId"); 
     Property(t => t.RoleId).HasColumnName("RoleId"); 
    } 
} 

internal class ReproLoginMap : EntityTypeConfiguration<ReproLogin> 
{ 
    public ReproLoginMap() 
    { 
     HasKey(l => l.UserId); 

     ToTable(typeof(ReproLogin).Name + 's'); 

     Property(t => t.UserId).HasColumnName("UserId"); 
     Property(t => t.LoginProvider).HasColumnName("LoginProvider"); 
     Property(t => t.ProviderKey).HasColumnName("ProviderKey"); 
    } 
} 

internal class ReproClaimMap : EntityTypeConfiguration<ReproClaim> 
{ 
    public ReproClaimMap() 
    { 
     ToTable(typeof(ReproClaim).Name + 's'); 

     Property(t => t.Id).HasColumnName("Id"); 
     Property(t => t.UserId).HasColumnName("UserId"); 
     Property(t => t.ClaimType).HasColumnName("ClaimType"); 
     Property(t => t.ClaimValue).HasColumnName("ClaimValue"); 
    } 
} 

internal class ReproRoleMap : EntityTypeConfiguration<ReproRole> 
{ 
    public ReproRoleMap() 
    { 
     ToTable(typeof(ReproRole).Name + 's'); 

     Property(t => t.Id) 
      .HasColumnName("Id"); 

     Property(r => r.Name) 
      .HasColumnName("Name") 
      .IsRequired() 
      .HasMaxLength(64) 
      .HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("RoleNameIndex") { IsUnique = true })); 

     HasMany(r => r.Users) 
      .WithRequired() 
      .HasForeignKey(ur => ur.RoleId); 
    } 
} 

internal class ReproUserMapping : EntityTypeConfiguration<ReproUser> 
{ 
    public ReproUserMapping() 
    { 
     HasKey(u => u.Id); 

     ToTable("ReproUser"); 

     HasMany(u => u.Roles) 
      .WithRequired() 
      .HasForeignKey(ur => ur.UserId); 

     HasMany(u => u.Claims) 
      .WithRequired() 
      .HasForeignKey(uc => uc.UserId); 

     HasMany(u => u.Logins) 
      .WithRequired() 
      .HasForeignKey(l => l.UserId); 

     Property(u => u.UserName) 
      .IsRequired() 
      .HasMaxLength(128) 
      .HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("UserNameIndex") { IsUnique = true })); 

     Property(u => u.Email) 
      .HasMaxLength(128); 

     Property(u => u.Id) 
      .HasColumnName("Id"); 
    } 
} 

です。私は(それが最初の1の後の最初の移行だと仮定)、その時点での移行をしようとした場合、私は次のエラーを取得する

System.Data.Entity.ModelConfiguration.ModelValidationException: One or more validation errors were detected during model generation: 

ReproUser_Logins_Target: : Multiplicity is not valid in Role 'ReproUser_Logins_Target' in relationship 'ReproUser_Logins'. Because the Dependent Role refers to the key properties, the upper bound of the multiplicity of the Dependent Role must be '1'. 

    at System.Data.Entity.Core.Metadata.Edm.EdmModel.Validate() 
    at System.Data.Entity.DbModelBuilder.Build(DbProviderManifest providerManifest, DbProviderInfo providerInfo) 
    at System.Data.Entity.DbModelBuilder.Build(DbConnection providerConnection) 
    at System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext) 
    at System.Data.Entity.Internal.RetryLazy`2.GetValue(TInput input) 
    at System.Data.Entity.Internal.LazyInternalContext.InitializeContext() 
    at System.Data.Entity.Internal.LazyInternalContext.get_ModelBeingInitialized() 
    at System.Data.Entity.Infrastructure.EdmxWriter.WriteEdmx(DbContext context, XmlWriter writer) 
    at System.Data.Entity.Utilities.DbContextExtensions.<>c__DisplayClass1.<GetModel>b__0(XmlWriter w) 
    at System.Data.Entity.Utilities.DbContextExtensions.GetModel(Action`1 writeXml) 
    at System.Data.Entity.Utilities.DbContextExtensions.GetModel(DbContext context) 
    at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration, DbContext usersContext, DatabaseExistenceState existenceState, Boolean calledByCreateDatabase) 
    at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration) 
    at System.Data.Entity.Migrations.Design.MigrationScaffolder..ctor(DbMigrationsConfiguration migrationsConfiguration) 
    at System.Data.Entity.Migrations.Design.ToolingFacade.ScaffoldRunner.Run() 
    at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate) 
    at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate) 
    at System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner) 
    at System.Data.Entity.Migrations.Design.ToolingFacade.Scaffold(String migrationName, String language, String rootNamespace, Boolean ignoreChanges) 
    at System.Data.Entity.Migrations.AddMigrationCommand.Execute(String name, Boolean force, Boolean ignoreChanges) 
    at System.Data.Entity.Migrations.AddMigrationCommand.<>c__DisplayClass2.<.ctor>b__0() 
    at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command) 
One or more validation errors were detected during model generation: 

ReproUser_Logins_Target: : Multiplicity is not valid in Role 'ReproUser_Logins_Target' in relationship 'ReproUser_Logins'. Because the Dependent Role refers to the key properties, the upper bound of the multiplicity of the Dependent Role must be '1'. 

私は、ユーザーマッピングにログインを削除しようとすると、物事ははるかに奇妙になるだろう。マイグレーションが発生しますが、ログインテーブルが1つのUserId実体フィールドの2つの列を取得します

CreateTable(
    "dbo.ReproLogins", 
    c => new 
     { 
      UserId = c.Int(nullable: false, identity: true), 
      LoginProvider = c.String(unicode: false), 
      ProviderKey = c.String(unicode: false), 
      ReproUser_Id = c.Int(), 
     }) 
    .PrimaryKey(t => t.UserId) 
    .ForeignKey("dbo.ReproUser", t => t.ReproUser_Id) 
    .Index(t => t.ReproUser_Id); 

私にとって非常に不自然ReproUser_Id思われます。たとえLoginProvidersをまったく使用しないとしても、私は本当にそれが存在しているのか混乱しています。

質問があります: Users 0..1 - 0..* LoginsのDBへの初歩的な列やエラーを取得することなくどのようにマップするのですか?

How to resolve " Multiplicity is not valid in Role" error?解決策は私のために働いていません。また、別のユーザークラスを追加する段階では、ベースログインクラスにナビゲーションプロパティが必要であるため、共通の汎用メソッドではなく、両方のマッピングを明示的に指定する必要があるため、いくつかの問題が発生します。

答えて

1

エラーメッセージをより正確に読み取ると、エラーの理由が明確になります。多重度の問題を解決するための鍵は、「従属ロールはのキープロパティ ...」を参照するためです。だから、エラーの理由はloginsuserをマップしようとしているのに対し、loginsにはUserIdがプライマリと外部キーの両方としてあるということです。しかし、プライマリキーは一意でなければならないため、この関係では単一のユーザーの外部キーにはなりません。

したがって、元のloginsテーブルPKをIdentity Frameworkから元に戻すことです。 UserId+LoginProvider+ProviderKeyに設定します。

関連する問題