EF Unidirectional One to Many关系

时间:2013-12-10 16:06:49

标签: c# entity-framework asp.net-mvc-5

我有一个 IdentityUser 类,它有一个名为登录的导航属性,类型为集合

public class IdentityUser : IUser
{
    public IdentityUser();
    public IdentityUser(string userName);

    public virtual ICollection<IdentityUserClaim> Claims { get; }
    public virtual string Id { get; set; }
    public virtual ICollection<IdentityUserLogin> Logins { get; }
    public virtual string PasswordHash { get; set; }
    public virtual ICollection<IdentityUserRole> Roles { get; }
    public virtual string SecurityStamp { get; set; }
    public virtual string UserName { get; set; }
}

IdentityUserLogin 类中,有一个名为用户的导航属性,其类型为 IdentityUser

public class IdentityUserLogin
{
    public IdentityUserLogin();

    public virtual string LoginProvider { get; set; }
    public virtual string ProviderKey { get; set; }
    public virtual IdentityUser User { get; set; }
    public virtual string UserId { get; set; }
}

从中我可以看出

  1. IdentityUser 可以包含0到多个 IdentityUserLogin
  2. IdentityUserLogin 必须有 IdentityUser
  3. 我试过了:

            this.HasRequired(t => t.User)
                .WithRequiredPrincipal();
    

    但它正在寻找 IdentityUser_Id 的外键,但它应该使用 UserId (这是 IdentityUserLogin的属性

    然后我尝试了:

            this.HasRequired(t => t.User)
                .WithMany(t => t.Logins)
                .HasForeignKey(t => t.UserId);
    

    但我收到错误声明:

      

    IdentityUserLogin_User_Source :: Multiplicity在关系'IdentityUserLogin_User'中的角色'IdentityUserLogin_User_Source'中无效。由于“从属角色”是指关键属性,因此从属角色的多重性的上限必须为“1”。

    有谁知道如何声明关系并指定外键?

    更新1

    这是我的 IdentityUserLogin 地图类:

    public class IdentityUserLoginMap : EntityTypeConfiguration<IdentityUserLogin>
    {
        public IdentityUserLoginMap()
        {
            // Primary Key
            this.HasKey(t => t.UserId);
    
            // Properties
            this.Property(t => t.LoginProvider)
                .IsRequired()
                .HasMaxLength(128);
    
            this.Property(t => t.ProviderKey)
                .IsRequired()
                .HasMaxLength(128);
    
            this.Property(t => t.UserId)
                .IsRequired()
                .HasMaxLength(128);
    
            // Table & Column Mappings
            this.ToTable("IdentityUserLogins");
            this.Property(t => t.LoginProvider).HasColumnName("LoginProvider");
            this.Property(t => t.ProviderKey).HasColumnName("ProviderKey");
            this.Property(t => t.UserId).HasColumnName("UserId");
    
            // Relationships
            this.HasRequired(t => t.User)
                .WithRequiredPrincipal();
        }
    }
    

    如您所见,我正在设置主键

    更新2

    只是给出更多解释,这是用户表:

    CREATE TABLE [dbo].[IdentityUsers](
        [Id] [nvarchar](128) NOT NULL,
        [UserName] [nvarchar](max) NULL,
        [PasswordHash] [nvarchar](max) NULL,
        [SecurityStamp] [nvarchar](max) NULL,
        [Discriminator] [nvarchar](128) NOT NULL,
     CONSTRAINT [PK_dbo.IdentityUsers] PRIMARY KEY CLUSTERED 
    (
        [Id] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    )
    

    并且 IdentityUserLogin 表应如下所示:

    CREATE TABLE [dbo].[IdentityUserLogins](
        [LoginProvider] [nvarchar](128) NOT NULL,
        [ProviderKey] [nvarchar](128) NOT NULL,
        [UserId] [nvarchar](128) NOT NULL,
    PRIMARY KEY CLUSTERED 
    (
        [UserId] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    

    但是当我在新数据库上运行我的代码时,我得到了这个:

    CREATE TABLE [dbo].[IdentityUserLogins](
        [UserId] [nvarchar](128) NOT NULL,
        [LoginProvider] [nvarchar](128) NOT NULL,
        [ProviderKey] [nvarchar](128) NOT NULL,
        [IdentityUser_Id] [nvarchar](128) NULL,
     CONSTRAINT [PK_dbo.IdentityUserLogins] PRIMARY KEY CLUSTERED 
    (
        [UserId] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    

    如您所见, IdentityUser_Id 已过时,应该使用主键。 这是我的目标:)

1 个答案:

答案 0 :(得分:-1)

您可能会因为未向班级IdentityUserLogin提供主键属性而使EF感到困惑。 我认为在这种情况下,EF将UserId作为您的主键。由于主键不能重复,并且您映射的关系显示为WithMany,因此它们相互冲突。

更新1

这与您的模型相冲突:

this.HasRequired(t => t.User).WithRequiredPrincipal();

因为在课程IdentityUser上你有

public virtual ICollection<IdentityUserLogin> Logins { get; set; }

您需要使用WithMany(t => t.Logins)才能使您的配置与模型匹配。

更新2
这是你需要的一对一关系

public class IdentityUser
{
  ... 
  public virtual IdentityUserLogin Login { get; set; }
  ...
}

this.HasRequired(t => t.User).WithRequiredPrincipal(t => t.Login);