EF6 迁移 MVC5 身份 2.1 - 多重性在角色中无效

EF6 Migrations MVC5 Identity 2.1 - Multiplicity is not valid in Role

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

因此,我有三个类似的 class 国家、州、城市(显示 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 class:

中有这段额外的代码块
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 '*'.

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

得到了做 FK 的想法

我也愿意用其他方式来做这件事,因为我正在考虑用所有这些信息做一个 UserSettings table,然后用 UserId 或类似的东西做一个 FK contraint。但是,这种方式对我来说似乎是多余的table。

感谢您的帮助。

问题是您正在创建三个一对一关系,在这种关系中,EF 期望两个相关的 table 共享相同的主键值(一个 [=19 的主键=]也是对方的PK和外键),但是我觉得你的情况不是这样的,因为同一个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 实体执行相同的操作。

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

在我的最后一段中,我注意到我愿意用其他方式来做...下面的 msdn 博客也准确描述了我所指的内容(有一个单独的用户设置 table 由一个链接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 迁移内容并回到我开始的地方。也许我会重新开始……再……