【问题标题】:How to reference ASP.Net Identity User Email property as Foreign Key如何将 ASP.Net 身份用户电子邮件属性引用为外键
【发布时间】:2017-02-21 22:46:33
【问题描述】:

尝试将 ASP.Net 身份用户的电子邮件属性作为外键引用,但不断收到错误消息

使用 MVC6、EF7

我有一个 AppAccount 是主要模型,ApplicationUser: IdentityUser 是依赖模型。

我正在尝试将ApplicationUser 的Email 属性设置为AppAccount 模型的外键

public class AppAccount
{
    public string AppAccountID { get; set; }

    public string AccountType { get; set; }

    public DateTime DateCreated { get; set; }

    public virtual ApplicationUser AppUser { get; set; }

}


public class ApplicationUser : IdentityUser
{

    public string FirstName { get; set; }

    public string Surname { get; set; }

    public DateTime DOB { get; set; }

    public virtual AppAccount AppAccount { get; set; }

}

IdentityUser 定义的“Peeking”告诉我 Email 属性是字符串类型...

public class IdentityUser<TKey> where TKey : IEquatable<TKey>
{
    ...
    //
    // Summary:
    //     Gets or sets the email address for this user.
    public virtual string Email { get; set; }
...
}

我已将AppAccount 模型的PK 设置为字符串,并将ApplicationUser 的Email 属性设为备用键,然后使用流式API 设置一对一关系...

builder.Entity<ApplicationUser>(au =>
            {
                au.HasAlternateKey(u => u.Email);
                au.HasAlternateKey(u => u.UserName);    
            });

        builder.Entity<AppAccount>(aa =>
        {
            aa.HasKey(a => a.AppAccountID);
            aa.HasOne(a => a.AppUser)
            .WithOne(u => u.AppAccount)
            .HasPrincipalKey<ApplicationUser>(u => u.Email);  // PK of AppAccount is FK of AppUser
        });

当我运行迁移时,它工作正常,但是当我尝试更新数据库时,我收到以下错误

Error Number:1753,State:0,Class:16
Column 'AspNetUsers.Email' is not the same length or scale as 
referencing column 'AppAccount.AppAccountID' 
in foreign key 'FK_AppAccount_ApplicationUser_AppAccountID'. 
Columns participating in a foreign key relationship must 
be defined with the same length and scale.
Could not create constraint or index. See previous errors.

我尝试手动将AppAccountID 和Email 属性的最大长度设置为相同的限制

builder.Entity<ApplicationUser>(au =>
            {
                ...
                au.Property(u => u.Email).HasMaxLength(100);    
            });

builder.Entity<AppAccount>(aa =>
        {
            ...
            aa.Property(a => a.AppAccountID).HasMaxLength(100);
            ...
        });

我已经尝试在服务器上将这两个属性设置为相同的类型...

builder.Entity<ApplicationUser>(au =>
            {
                ...
                au.Property(u => u.Email).ForSqlServerHasColumnType("nvarchar(100)");    
            });

builder.Entity<AppAccount>(aa =>
        {
            ...
            aa.Property(a => a.AppAccountID).ForSqlServerHasColumnType("nvarchar(100)");
            ...
        });

尝试将ApplicationUser 类中的Email 属性覆盖为

public override string Email {get ; set ;}

我尝试将AppAccount 模型的AppAccountID 属性设置为virtual

`public virtual string AppAccountID {get ; set ;}

我认为这可能是服务器问题,但检查数据库 Email 列类型是 nvarchar,所以我不明白为什么它无法编译?

【问题讨论】:

  • 如错误提示,检查邮件是否有模型中定义的长度属性
  • Columns participating in a foreign key relationship must be defined with the same length and scale 意味着您需要检查外部关系、数据类型以及链接列的长度。您也可以在OnModelCreating 方法中尝试HasForeignKey。
  • @LibinJoseph - 我可以看到模型中没有定义长度属性,尝试在之前尝试解决问题时覆盖长度属性无效。
  • @TetsuyaYamamoto - 按照建议在OnModelCreating 内尝试使用HasForeignKey,但仍然收到相同的错误。仍在寻找 FK 和数据类型差异...
  • @Scheeeve 我无法重现这个 - 如果我设置相同的长度(HasMaxLength(x))它对我有用。在OnModelCreating 方法中调用base.OnModelCreating(builder) 后是否添加自定义?

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


【解决方案1】:

试试这个模型

public class AppAccount
{
public string AppAccountID { get; set; }

public string AccountType { get; set; }

public DateTime DateCreated { get; set; }
[ForeignKey("UserId")
public virtual ApplicationUser AppUser { get; set; }

}

【讨论】:

  • 添加 [ ForeignKey ("UserId")] 注释会将 FK 关系指向错误的列。我确实尝试将ForeignKey ("Email")] 添加到模型中,但在尝试更新数据库时仍然收到相同的错误
【解决方案2】:

抱歉,业余时间

首先我写的是HasPrincipleKey,而不是@TetsuyaYamamoto 指出的HasForeignKey(谢谢)。

其次,在无数次检查数据库后,ApplicationUser 的Email 属性的类型为NVARCHAR(256),因此如下更新自定义允许 EF 成功编译模型。

builder.Entity<AppAccount>(aa =>
        {
            aa.HasKey(a => a.AppAccountID);
            aa.Property(a => a.AppAccountID).ForSqlServerHasColumnType("NVARCHAR(256)");
            aa.HasOne(a => a.AppUser)
            .WithOne(u => u.AppAccount)
            .HasForeignKey<ApplicationUser>(u => u.Email);
        });

谢谢大家...这就是为什么您不在凌晨 1 点编码的原因

【讨论】:

    猜你喜欢
    • 2013-12-21
    • 1970-01-01
    • 2016-10-24
    • 1970-01-01
    • 2018-07-31
    • 2013-11-14
    • 2020-07-13
    • 1970-01-01
    • 2015-02-14
    相关资源
    最近更新 更多