【问题标题】:Entity Framework 6 1 to 1 relationship mapping not working实体框架 6 1 对 1 关系映射不起作用
【发布时间】:2014-04-15 01:08:40
【问题描述】:

我将 Entity Framework 6 与现有数据库一起使用,并从旧的自定义身份验证系统迁移了一些数据。

我有两个模型,一个扩展了 MVC5 中的脚手架 ApplicationUser (Identity),另一个是旧表的模型。这些表具有一对一的关系。

因为我的身份验证表的 UserId 曾经是一个 int,而 ASP.NET Identity 2 将 ID 定义为一个 guid,所以我使用旧的 UserId(它是 tbl0102User 的主键)创建了关联。

所以表格是:

AspNetUsers:

- Id (guid)
- Username etc
- UserId (int) - this is the column I have created on the table to map to the old User table

Tbl01012Users:

 - UserId (int)
 - address etc...

我对这两个模型的代码是:

 public class ApplicationUser : IdentityUser
    {
        public int UserId { get; set; }

        [ForeignKey("UserId")]
        public UserDetails Details { get; set; }
    }

[Table("tbl0102User")]
public class UserDetails
{
    // This numeric id contains the relationship between the old authentication system and the new ASP.NET Identity.
    // The new system has a Guid as Id, but that is different to the UserId.
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }

    public ApplicationUser AppUser { get; set; }

    public string UserLogin { get { return AppUser.UserName; } }

    // etc....
}

当我尝试构建和运行应用程序时,我收到以下错误:

System.InvalidOperationException: Unable to determine the principal end of an association between the types 'Plus.Models.ApplicationUser' and 'Plus.Models.UserDetails'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.
   at System.Data.Entity.ModelConfiguration.Edm.Services.AssociationTypeMappingGenerator.GenerateIndependentAssociationType(AssociationType associationType, DbDatabaseMapping databaseMapping)
   at System.Data.Entity.ModelConfiguration.Edm.Services.DatabaseMappingGenerator.GenerateAssociationTypes(DbDatabaseMapping databaseMapping)
   at System.Data.Entity.ModelConfiguration.Edm.Services.DatabaseMappingGenerator.Generate(EdmModel conceptualModel)
   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_CodeFirstModel()
   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)
   at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration)
   at System.Data.Entity.Migrations.Design.ToolingFacade.BaseRunner.GetMigrator()
   at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.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.Update(String targetMigration, Boolean force)
   at System.Data.Entity.Migrations.UpdateDatabaseCommand.<>c__DisplayClass2.<.ctor>b__0()
   at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command)

这是为什么?我在 ApplicationUser 对象上指定了 Details 属性的外键根据 UserDetails 对象上的外键 userId 映射。

我怎样才能改变它来工作?

我也尝试过流畅的映射,根据:http://msdn.microsoft.com/en-au/data/jj713564.aspx

 protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<UserDetails>()
                .HasOptional(t => t.AppUser)
                .WithRequired(t => t.Details)
                ;            
        }

但得到错误:

UserDetails_AppUser_Target: : Multiplicity is not valid in Role 'UserDetails_AppUser_Target' in relationship 'UserDetails_AppUser'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'.

我也试过了:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<UserDetails>()
                .HasRequired(x=>x.AppUser)
                .WithRequiredDependent(y=>y.Details)               
                ;            
        }

但是,我得到了错误:

UserDetails_AppUser_Target_UserDetails_AppUser_Source: : The types of all properties in the Dependent Role of a referential constraint must be the same as the corresponding property types in the Principal Role. The type of property 'UserId' on entity 'UserDetails' does not match the type of property 'Id' on entity 'ApplicationUser' in the referential constraint 'UserDetails_AppUser'.

对我来说,这说明它没有正确获取 ApplicationUser 上的外键,而是使用主键 ID (guid)。

【问题讨论】:

    标签: c# ef-code-first asp.net-mvc-5 entity-framework-6


    【解决方案1】:

    我找到了答案:

    public class ApplicationUser : IdentityUser
    {
        public int UserId { get; set; }
    
        [ForeignKey("UserId")]
        public virtual UserDetails Details { get; set; }
    }
    

    我不确定这与我原来的有什么不同,除了我将 UserDetails 对象标记为虚拟。

    【讨论】:

      【解决方案2】:

      您可以尝试如下指定外键:

      public class ApplicationUser : IdentityUser
      {
          [ForeignKey("UserDetails")]
          public int UserId { get; set; }
      
          public UserDetails Details { get; set; }
      }
      

      另一种选择可能是在 UserDetails 中的 ApplicationUser 属性上使用 Required 属性。

      【讨论】:

      • 这不起作用。我收到以下错误:'Plus.Models.ApplicationUser' 类型的属性 'UserId' 上的 ForeignKeyAttribute 无效。在依赖类型“Plus.Models.ApplicationUser”上找不到导航属性“UserDetails”。 Name 值应该是有效的导航属性名称。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-27
      • 1970-01-01
      相关资源
      最近更新 更多