将标识与自定义属性和关系一起使用时出错"The INSERT statement conflicted with the FOREIGN KEY constraint "



我是asp.net MVC的新手,我正在练习构建这个应用程序。

我正在尝试向visualstudio生成的默认IdentityModel.cs添加一个自定义属性。该客户财产将持有用户所属的大学图书馆。

如果我把这篇文章写得太大,我很抱歉,但我真的不知道是什么导致了问题,我应该省略什么。

到目前为止我所做的:创建了大学图书馆实体:

 public class UniversityLibrary
{
    [Key]
    public int UniversityLibraryId { get; set; }
    public string UniversityLibraryName { get; set; }
    public virtual ICollection<ApplicationUser> Users {get;set;}
}

将自定义属性添加到IdentityModel.cs:

public class ApplicationUser : IdentityUser
{
public virtual UniversityLibrary UniversityLibraries { get; set; }  
public int UniversityLibraryId { get; set; }
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        return userIdentity;
    }
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("name=DefaultConnection", throwIfV1Schema: false)
    {
    }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
    }
    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }

}

在RegisterViewModel中添加了自定义属性:

public class RegisterViewModel
{

    [Required]
    [EmailAddress]
    [Display(Name = "Email")]
    public string Email { get; set; }
    [Required]
    [DisplayName("University Library ID")]
    public int UniversityLibraryId { get; set; }
    public virtual ICollection<UniversityLibrary> Libraries { get; set; }
    [Required]
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }
    [DataType(DataType.Password)]
    [Display(Name = "Confirm password")]
    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }
}

创建了一个大学图书馆列表,将使用actionfilter传递给我的视图:

public class ViewbagListOfUniversityLibraries : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        IncludeRoleListIntoViewBag(filterContext.Controller.ViewBag);
        base.OnActionExecuted(filterContext);
    }
    private void IncludeRoleListIntoViewBag(dynamic viewBag)
    {
        using (var db = new LibraryManagementWebAppContext())
        {
            viewBag.UniversityLibraryList = db.UniversityLibraries
                .OrderBy(x => x.UniversityLibraryName)
                .Select(unversityLibrary => new SelectListItem()
                {
                    Text = unversityLibrary.UniversityLibraryName,
                    Value = unversityLibrary.UniversityLibraryId.ToString()
                })
                .ToList();
        }
    }
}

修改了Register视图以添加大学图书馆的下拉列表:

@model LibraryManagementWebApp.Models.RegisterViewModel
@{
    ViewBag.Title = "Register";
    IEnumerable<SelectListItem> universityLibraryList = ViewBag.UniversityLibraryList;
}
...
<div class="form-group">
    @Html.LabelFor(m => m.UniversityLibraryId, new { @class = "col-md-2 control-label" })
    <div class="col-md-10">
        @Html.DropDownListFor(m => m.UniversityLibraryId, universityLibraryList,"Select One", new { @class = "form-control" })
    </div>
</div>

将模型构建器添加到我的另一个上下文(大学图书馆的上下文)中,因为它导致了错误,如"EntityType‘IdentityUserLogin’没有定义密钥。定义此EntityType的密钥"

public class LibraryManagementWebAppContext : DbContext
{
   public LibraryManagementWebAppContext() : base("name=LibraryManagementWebAppContext")
    {
    }
    public DbSet<UniversityLibrary> UniversityLibraries { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<IdentityUserLogin>().HasKey(l => l.UserId);
        modelBuilder.Entity<IdentityRole>().HasKey(r => r.Id);
        modelBuilder.Entity<IdentityUserRole>().HasKey(r => new { r.RoleId, r.UserId });
        modelBuilder.Entity<UniversityLibrary>().HasKey(r => r.UniversityLibraryId);
        base.OnModelCreating(modelBuilder);
    }
}

在我的数据库中创建新用户之前,修改了控制器以获得选定的值:

 [HttpPost]
    [AllowAnonymous]
    [ViewbagListOfUniversityLibraries]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Register(RegisterViewModel model)
    {
        if (ModelState.IsValid)
        {
            var user = new ApplicationUser { UserName = model.Email, Email = model.Email, UniversityLibraryId = Convert.ToInt32(model.UniversityLibraryId) };
            var result = await UserManager.CreateAsync(user, model.Password);
            if (result.Succeeded)
            {
                await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);
                // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771
                // Send an email with this link
                // string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
                // var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
                // await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking <a href="" + callbackUrl + "">here</a>");
                return RedirectToAction("Index", "Home");
            }
            AddErrors(result);
        }
        // If we got this far, something failed, redisplay form
        return View(model);
    }

问题是:当我尝试注册一个新用户时,会出现以下错误:

The INSERT statement conflicted with the FOREIGN KEY constraint "FK_dbo.AspNetUsers_dbo.UniversityLibraries_UniversityLibraryId". The conflict occurred in database "ASPNET_LIBRARYMANAGEMENTWEBAPP_aa38b17e20d0416d8c53a3a5d0faa59e", table "dbo.UniversityLibraries", column 'UniversityLibraryId'.

我不知道该怎么解决。调试我的代码我可以看到我的用户变量有一个UniversityLibraryId的值。调试:传递给CreateAsync 的用户变量

同样已经在数据库和UniversityLibrary表中验证了具有相同id的项目。检查数据库以查看数据是否存在

好吧,所以我设法找到了我做错的地方。。。

由于我有两个上下文(一个是自动生成的"IdentityModel.cs",另一个是我在本教程之后生成的,为asp-netmvc应用程序创建实体框架数据模型)

每个上下文都指向不同的数据库,这两个数据库都有相同的表。

所以我成功地把";大学图书馆;在注册页面中使用,但它们是我们在错误的数据库中创建的。

然后我做了一些更改,使两个上下文指向同一个数据库,并使我的LibraryManagementWebAppContext继承自IdentityDbContext

我的大学图书馆背景:

public class LibraryManagementWebAppContext : IdentityDbContext<ApplicationUser>
{
   public LibraryManagementWebAppContext() : base("name=DefaultConnection")
    {
    }
    public DbSet<UniversityLibrary> UniversityLibraries { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
 
        modelBuilder.Entity<IdentityUserLogin>().HasKey(l => l.UserId);
        modelBuilder.Entity<IdentityRole>().HasKey(r => r.Id);
        modelBuilder.Entity<IdentityUserRole>().HasKey(r => new { r.RoleId, r.UserId });
        modelBuilder.Entity<UniversityLibrary>().HasKey(r => r.UniversityLibraryId);
        base.OnModelCreating(modelBuilder);
    }
    
}

以及visualstudio生成的默认IdentityModel:

 public ApplicationDbContext()
        : base("name=DefaultConnection", throwIfV1Schema: false)
    {
    }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
    }
    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }
   
}

在那之后,我放弃了数据库,可以成功地:1-创建大学图书馆2-使用我的大学图书馆列表注册用户

正如我之前所说,我对asp非常陌生。NET,所以我可能做了一些事情,即使工作也不是最好的方式。请随时补充我的答案或提出一些可以做的建议。

谢谢。

最新更新