繁体   English   中英

当我希望它更新时,实体正在尝试为相关表插入新记录

[英]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 已经在评论中指出的那样,这可能是由于ShoppingCartProject属性被发布在您的MakePayment方法上。 来自实体框架文档

但是,Add 方法不仅仅适用于单个实体。 他们实际上开始跟踪相关实体的整个图表,将它们全部添加到 Added state。例如,插入一个新博客和关联的新帖子

因此,如果您在数据库中不存在的ShoppingCart上发布Project ,实体框架将创建一个新项目。 如果Project存在,您之前的查询将跟踪它,我的猜测是 Entity Framework 将导航新附加的ShoppingCart并使用在shoppingCart.Project上找到的值编辑现有项目属性。

也许您可以查看更改调试信息,对于您要调试的问题,它看起来很有希望。

暂无
暂无

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

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