[英]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; }
}
UserProfile与Address类具有一对一关系。
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.