【问题标题】:EF6 Migrations MVC5 Identity 2.1 - Multiplicity is not valid in RoleEF6 迁移 MVC5 Identity 2.1 - 多重性在角色中无效
【发布时间】:2015-05-13 08:27:55
【问题描述】:

我基本上有一个新的 MVC5/EF6(个人用户身份验证)项目,我正在尝试稍微修改 Identity Users 表以包含国家、州和城市的 Id。我能够通过 EF 迁移成功创建新列,但是在尝试添加 FK 约束时遇到了障碍。我在默认的 Identity Users SQL 表中添加了 CountryId、StateId 和 CityId,所有这些都设置为可为空的 Int 值。

所以,我为 Country、State、City 设置了三个类似的类(显示了 State.cs):

public class State
    {
        [Key]
        public int StateId { get; set; }
        public string StateName { get; set; }

        [ForeignKey("Country")]
        public int CountryId { get; set; }

        public virtual Country Country { get; set; }
        public virtual ICollection<City> Cities { get; set; }
        public virtual ApplicationUser ApplicationUser { get; set; }
    }

然后我的 IdentityModels.cs ApplicationUser 类中有这段额外的代码:

public class ApplicationUser : IdentityUser
    {
        [ForeignKey("Country")]
        public int CountryId { get; set; }

        [ForeignKey("State")]
        public int StateId { get; set; }

        [ForeignKey("City")]
        public int CityId { get; set; }

        public virtual Country Country { get; set; }
        public virtual State State { get; set; }
        public virtual City City { get; set; }
// the rest is default....
}

看起来很简单。但是,在尝试添加迁移时它不喜欢我:

PM> Add-Migration AddLocaleForeignKeys
System.Data.Entity.ModelConfiguration.ModelValidationException: One or more validation errors were detected during model generation:

ApplicationUser_City_Source: : Multiplicity is not valid in Role 'ApplicationUser_City_Source' in relationship 'ApplicationUser_City'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'.
ApplicationUser_Country_Source: : Multiplicity is not valid in Role 'ApplicationUser_Country_Source' in relationship 'ApplicationUser_Country'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'.
ApplicationUser_State_Source: : Multiplicity is not valid in Role 'ApplicationUser_State_Source' in relationship 'ApplicationUser_State'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'.

   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:

ApplicationUser_City_Source: : Multiplicity is not valid in Role 'ApplicationUser_City_Source' in relationship 'ApplicationUser_City'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'.
ApplicationUser_Country_Source: : Multiplicity is not valid in Role 'ApplicationUser_Country_Source' in relationship 'ApplicationUser_Country'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'.
ApplicationUser_State_Source: : Multiplicity is not valid in Role 'ApplicationUser_State_Source' in relationship 'ApplicationUser_State'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'.

我在这里阅读了其他一些类似的问题,我希望有人可以在我的代码中向我展示(以精神上受挑战的术语)我做错了什么,因为我并没有真正从术语中得到它立场(或查看他们的代码)。我从基本上剖析了这个链接HERE

中得到了做FK的想法

我也愿意以其他方式做这件事,因为我正在考虑用所有这些信息做一个 UserSettings 表,然后用 UserId 或类似的东西做一个 FK 约束。但是,这种方式对我来说似乎是一个额外的不必要的表。

感谢您的帮助。

【问题讨论】:

    标签: c# sql-server asp.net-mvc entity-framework asp.net-identity


    【解决方案1】:

    问题是你正在创建三个一对一的关系,在这种关系中,EF 期望两个相关的表共享相同的主键值(一个表的主键也是主键和外键其他),但我认为这不是你的情况,因为同一个State 可能在多个ApplicationUsers 中,所以,你需要配置一个一对多的关系。

    public class State
    {
        [Key]
        public int StateId { get; set; }
    
        public virtual ICollection<ApplicationUser> ApplicationUsers { get; set; }
    }
    
    public class ApplicationUser : IdentityUser
    {
        //...
        [ForeignKey("State")]
        public int StateId { get; set; }
    
        public virtual State State { get; set; }
    }
    

    CountryCity 实体执行相同操作。

    【讨论】:

    • 谢谢,这似乎至少可以消除错误。虽然,该特定迁移的公共覆盖无效上下是空白的。因此,实际上不会将任何 FK 添加到数据库中……另外,我不确定我是否掌握了这一点。一个用户永远不会有超过一个国家/州/城市分配给它,并且有可能为空。所以,对我来说,这似乎是 1 对 0 或 1 的关系?该应用程序永远不会朝另一个方向看,即我永远不会查询州以在其中显示多个用户或列出一个州的多个用户。嗯,但是谢谢!
    【解决方案2】:

    对于我上面的问题,接受的答案在技术上是正确的。但是,我找到了另一个我正在寻找的答案(上面也提到过),这也巩固了我不赌博的原因。

    在我的最后一段中,我注意到我愿意以其他方式进行操作...以下 msdn 博客也准确描述了我所指的内容(具有由单个 FK 链接的单独用户设置表):

    http://blogs.msdn.com/b/webdev/archive/2013/10/16/customizing-profile-information-in-asp-net-identity-in-vs-2013-templates.aspx

    我意识到我可以做到这一点,但现在我正在查看一个无错误模型等(感谢 octavioccl),尝试从头开始生成代码肯定会让我的大脑爆炸。我现在纯粹是在仅从示例中学习的模式。无论如何,希望这个答案可以帮助其他人节省时间并克服这些学习障碍。

    现在,我必须看看我是否可以融化我的大脑,试图撤消所有 EF 迁移的东西并回到我开始的地方。也许我会重新开始......再次......

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-28
      • 2015-07-02
      • 2019-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多