[英]Entity is trying to insert a new record for a related table when I want it to update
我知道这是我理解实体和数据库表/关系如何工作的问题。我只是想弄清楚我在哪里犯了错误。
我有一个购物车表,带有指向相关项目表的外键。 我正在尝试向数据库中插入一条新的购物车记录,默认情况下,实体正在尝试插入一个新项目。 但是,我不想要一个新项目,我想要更新数据库中的现有项目。
这是购物车/项目的插入和更新代码:
public async Task<IActionResult> MakePayment(int? projectId)
{
ShoppingCart cart = new ShoppingCart()
{
ProjectId = projectId,
Project = await _dbContext.Projects.Where(p => p.Id == projectId).Select(p => new Project()
{
AmountPaid = p.AmountPaid,
RemainingBalance = p.RemainingBalance,
OriginalPrice = p.OriginalPrice
}).FirstOrDefaultAsync()
};
//set payment amount to remaining balance by default
cart.PaymentAmount = cart.Project.RemainingBalance;
return View(cart);
}
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize]
public async Task<IActionResult> MakePayment(ShoppingCart shoppingCart)
{
//get user id of logged in user
var claimsIdentity = (ClaimsIdentity)User.Identity;
var claim = claimsIdentity.FindFirst(ClaimTypes.NameIdentifier);
//if claim is null, that means we are not logged in
if(claim != null)//claim should never be null, because we are using the Authorize Data Annotation
{
shoppingCart.AppUserId = claim.Value;
//get the related project to update payment values
var dbProject = await _dbContext.Projects.Where(p => p.Id == shoppingCart.ProjectId).FirstOrDefaultAsync();
if(dbProject != null)
{
dbProject.AmountPaid += shoppingCart.PaymentAmount;
dbProject.RemainingBalance = dbProject.OriginalPrice - dbProject.AmountPaid;
}
await _dbContext.SaveChangesAsync();
}
await _dbContext.ShoppingCarts.AddAsync(shoppingCart);
await _dbContext.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
这是我的购物车和项目表的表模型(代码优先):
购物车表:
namespace FordWare.Models
{
public class ShoppingCart
{
#nullable disable
[Key]
[Required]
public int Id { get; set; }
#nullable enable
public string? AppUserId { get; set; }
#nullable enable
[ValidateNever]
public AppUser? AppUser { get; set; }
#nullable enable
public int? ProjectId { get; set; }
#nullable enable
[ValidateNever]
public Project? Project { get; set; }
#nullable enable
public double? PaymentAmount { get; set; }
}
}
项目表:
namespace FordWare.Models
{
public class Project
{
#nullable disable
[Required]
[Key]
public int Id { get; set; }
#nullable disable
[Required]
public string Description { get; set; }
#nullable enable
[ValidateNever]
[DisplayName("Image")]
public string? ImageURL { get; set; }
#nullable enable
public string? LinkToProject { get; set; }
#nullable enable
public double? OriginalPrice { get; set; }
#nullable enable
public double? AmountPaid { get; set; }
#nullable enable
public double? RemainingBalance { get; set; }
#nullable disable
[Required]
public string ServiceCSV { get; set; }
#nullable enable
[DisplayName("Company")]
public int? CompanyId { get; set; }
#nullable enable
[ForeignKey("CompanyId")]
[ValidateNever]
public Company? Company { get; set; }
#nullable disable
[Required]
public double EstimatedHours { get; set; }
#nullable disable
[Required]
public double EstimatedPrice { get; set; }
#nullable disable
[Required]
public DateTime TargetStartDate { get; set; }
#nullable disable
[Required]
public DateTime TargetCompletionDate { get; set; }
}
}
这是我在尝试添加新购物车时遇到的错误,然后将更改保存在数据库中。它正在尝试插入一个新项目,并且项目的描述列是必需的...所以它抛出了 null 错误...但是,我不想在这里插入一个新项目...我想它正在尝试这样做是因为 ShoppingCart model 上的项目导航属性:
正如@progman 已经在评论中指出的那样,这可能是由于ShoppingCart
的Project
属性被发布在您的MakePayment
方法上。 来自实体框架文档:
但是,Add 方法不仅仅适用于单个实体。 他们实际上开始跟踪相关实体的整个图表,将它们全部添加到 Added state。例如,插入一个新博客和关联的新帖子
因此,如果您在数据库中不存在的ShoppingCart
上发布Project
,实体框架将创建一个新项目。 如果Project
存在,您之前的查询将跟踪它,我的猜测是 Entity Framework 将导航新附加的ShoppingCart
并使用在shoppingCart.Project
上找到的值编辑现有项目属性。
也许您可以查看更改调试信息,对于您要调试的问题,它看起来很有希望。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.