繁体   English   中英

ASP .NET一对一关系CRUD

[英]ASP .NET One-to-One Relationship CRUD

在基于代码优先的类UserProfile的情况下,控制器自动生成的Edit操作存在问题。

public class UserProfile : ApplicationUser
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime BirthDate { get; set; }
        public string ProfilePhoto { get; set; }
        public string Interests { get; set; }
        public string AboutMe { get; set; }

        public Address Address { get; set; }
        public List<Post> Posts { get; set; }
        public List<Friends> Friends { get; set; }
        public List<Messages> Messages { get; set; }
        public List<UsersGallery> UsersGallery { get; set; }
    }

UserProfileAddress类具有一对一关系。

public class Address
    {
        [Key]
        public string AddressId { get; set; }

        public string City { get; set; }
        public string Street { get; set; }
        public string HouseOrFlatNumber { get; set; }
        public string PostalCode { get; set; }
        public string Country { get; set; }

        public string UserProfileForeignKey { get; set; }
        public UserProfile UserProfile { get; set; }
    }

该关系在FluentApi中描述如下:

protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);

            builder.Entity<UserProfile>()
            .HasOne(p => p.Address)
            .WithOne(i => i.UserProfile)
            .HasForeignKey<Address>(b => b.UserProfileForeignKey);
        }

注册操作中创建UserProfile和Address实体

public async Task<IActionResult> Register(RegisterViewModel model, string returnUrl = null)
        {
            ViewData["ReturnUrl"] = returnUrl;
            if (ModelState.IsValid)
            {
                var user = new UserProfile { UserName = model.FirstName, Email = model.Email, FirstName = model.FirstName, LastName = model.LastName, Address = new Address() };
                var result = await _userManager.CreateAsync(user, model.Password);
                if (result.Succeeded)
                {
                    _logger.LogInformation("User created a new account with password.");

                    var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
                    var callbackUrl = Url.EmailConfirmationLink(user.Id, code, Request.Scheme);
                    await _emailSender.SendEmailConfirmationAsync(model.Email, callbackUrl);

                    await _signInManager.SignInAsync(user, isPersistent: false);
                    _logger.LogInformation("User created a new account with password.");
                    return RedirectToLocal(returnUrl);
                }
                AddErrors(result);
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

此时,我在与UserProfileForeignKey相关的数据库表中具有适当的条目。 -UserProfile表UserProfile表-Address表 Address表

这里出现了一个问题。 根据sql错误消息,自动生成的CRUD操作“ 编辑”而不是更改“地址”表中的条目,而是尝试使用相同的UserProfileForeignKey添加新条目。

我理解正确吗? 为什么会这样,如何做才能使“编辑”操作按预期进行?

[HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Edit(string id, [Bind("FirstName,LastName,BirthDate,ProfilePhoto,Interests,AboutMe,Address,Id,UserName,NormalizedUserName,Email,NormalizedEmail,EmailConfirmed,PasswordHash,SecurityStamp,ConcurrencyStamp,PhoneNumber,PhoneNumberConfirmed,TwoFactorEnabled,LockoutEnd,LockoutEnabled,AccessFailedCount")] UserProfile userProfile)
        {
            if (id != userProfile.Id)
            {
                return NotFound();
            }

            if (ModelState.IsValid)
            {
                try
                {
                    _context.Update(userProfile);
                    await _context.SaveChangesAsync();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!UserProfileExists(userProfile.Id))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
                return RedirectToAction(nameof(Index));
            }
            return View(userProfile);
        }

这是sql错误消息:

处理请求时发生未处理的异常。

SqlException:无法在具有唯一索引“ IX_Address_UserProfileForeignKey”的对象“ dbo.Address”中插入重复的键行。

重复的密钥值为(9872561e-dad4-4169-9faf-154c7dcd925f)。 该语句已终止。

System.Data.SqlClient.SqlCommand + <> c.b__108_0(任务结果)DbUpdateException:更新条目时发生错误。 有关详细信息,请参见内部异常。

Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch + d__32.MoveNext()

它说,试图复制ForeignKey 9872561e-dad4-4169-9faf-154c7dcd925f ,但为什么它是更新而不是插入?

这是因为您的UserProfile实体是分离的(实体框架未对其进行跟踪),因此它设置了entity.State ==此处添加。 要附加您的实体,请参阅如何更新现有的断开连接的实体

编辑27/01/2018我试图复制您的场景并在GitHub https://github.com/updateaman/EF6-Test中创建了一个项目

在设置/传递Address对象内的UserProfileForeignKey属性后,我能够摆脱此错误

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM