首页 > 解决方案 > 将多个类添加到购物车类.net mvc 5

问题描述

我正在尝试提出一个汽车服务预订应用程序,该应用程序允许一个人将汽车预订到服务中并购买一些零件,这不是必需的,但我收到如下错误:

SqlException:INSERT 语句与 FOREIGN KEY 约束“FK_dbo.BasketLines_dbo.Parts_PartID”冲突。冲突发生在数据库“aspnet-Noir-20190224082924”、表“dbo.Parts”、列“PartId”中。该语句已终止。

我的课程如下:

部分

public class Part
{
    [Key]
    public int PartId { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public byte[] ImageFile { get; set; }
    public string ImageFilePath { get; set; }
    public decimal Price { get; set; }
    public virtual ICollection<ServicePartMapping> 
    ServicePartMappings { get; set;}
}

服务

public class Service
{
    public int  ServiceId { get; set; }
    public string Name { get; set; }
    public string Type { get; set; }
    public decimal Price { get; set; }
    public ICollection<Part> Parts { get; set; }
}

服务部件映射

public class ServicePartMapping
{
    public int ServicePartMappingID { get; set; }
    public int PartNumber { get; set; }
    public int? ServiceId { get; set; }
    public int? ServicePartId { get; set; }
    public virtual Service Service { get; set; }
    public virtual ServicePart ServicePart { get;   
    set; }
}

篮子

public class Basket
{

    public int Id { get; set; }

    private string BasketID { get; set; }

    private const string BasketSessionKey = 
    "BasketID";

    private ApplicationDbContext db = new 

    ApplicationDbContext();

    private string GetBasketID()
    {
        if 
     (HttpContext.Current.Session[BasketSessionKey] 
      == null)
        {
            if 
             (!string.IsNullOrWhiteSpace 
             (HttpContext.Current 
             .User.Identity.Name))
            {
            HttpContext.Current
            .Session[BasketSessionKey] =  
            HttpContext.Current 
            .User.Identity.Name;
            }
            else
            {

                Guid tempBasketID = Guid.NewGuid()  
                HttpContext.Current 
                .Session[BasketSessionKey] 
                = tempBasketID.ToString();
            }
        }
        return 
        HttpContext.Current
        .Session[BasketSessionKey].ToString();
    }
    public static Basket GetBasket()
    {
        Basket basket = new Basket();

        basket.BasketID = basket.GetBasketID();

        return basket;
    }

    public void AddServiceToBasket(int serviceID, 
    int quantity)
    {
        var basketLine = 
        db.BasketLines.FirstOrDefault(b => 
        b.BasketID == BasketID && b.ServiceID
         == serviceID);

        if (basketLine == null)
        {
            basketLine = new BasketLine
            {
                ServiceID = serviceID,
                BasketID = BasketID,
                Quantity = quantity,
                DateCreated = DateTime.Now
            };
            db.BasketLines.Add(basketLine);
        }
        else
        {
            basketLine.Quantity += quantity;
        }
        db.SaveChanges();
    }

    public void AddPartToBasket(int partID, int 
    quantity)
    {
        var basketLine = 
        db.BasketLines.FirstOrDefault(b => 
        b.BasketID == BasketID && b.PartId
         == partID);

        if (basketLine == null)
        {
            basketLine = new BasketLine
            {
                PartId = partID,
                BasketID = BasketID,
                Quantity = quantity,
                DateCreated = DateTime.Now
            };
            db.BasketLines.Add(basketLine);
        }
        else
        {
            basketLine.Quantity += quantity;
        }
        db.SaveChanges();
    }
    public void RemoveLine(int ID)
    {
        var basketLine = db.BasketLines.FirstOrDefault(b => b.BasketID == BasketID && b.ServiceID
         == ID || b.PartId == ID);
        if (basketLine != null)
        {
            db.BasketLines.Remove(basketLine);
        }
        db.SaveChanges();
    }

    public void UpdateBasket(List<BasketLine> lines)
    {
        foreach (var line in lines)
        {
            var basketLine = db.BasketLines.FirstOrDefault(b => b.BasketID == BasketID &&
             b.ServiceID == line.ServiceID);
            if (basketLine != null)
            {
                if (line.Quantity == 0)
                {
                    RemoveLine(line.ServiceID);
                }
                else
                {
                    basketLine.Quantity = line.Quantity;
                }
            }
        }
        db.SaveChanges();
    }

    public void EmptyBasket()
    {
        var basketLines = db.BasketLines.Where(b => b.BasketID == BasketID);
        foreach (var basketLine in basketLines)
        {
            db.BasketLines.Remove(basketLine);
        }
        db.SaveChanges();
    }

    public List<BasketLine> GetBasketLines()
    {
        return db.BasketLines.Where(b => b.BasketID == BasketID).ToList();
    }

    public decimal GetTotalCost()
    {
        decimal basketTotal = decimal.Zero;
        decimal serviceTotal = decimal.Zero;
        decimal partTotal = decimal.Zero;
        if (GetBasketLines().Count > 0)
        {
            serviceTotal = db.BasketLines.Where(b => b.BasketID == BasketID).Sum(b => b.Service.Price
             * b.Quantity);

            partTotal = db.BasketLines.Where(b => b.BasketID == BasketID).Sum(b => b.Part.Price
            * b.Quantity);

            basketTotal = serviceTotal + partTotal;

        }

        return basketTotal;
    }

    public int GetNumberOfItems()
    {
        int numberOfItems = 0;
        if (GetBasketLines().Count > 0)
        {
            numberOfItems = db.BasketLines.Where(b => b.BasketID == BasketID).Sum(b => b.Quantity);
        }

        return numberOfItems;
    }

    public void MigrateBasket(string userName)
    {
        //find the current basket and store it in memory using ToList()
        var basket = db.BasketLines.Where(b => b.BasketID == BasketID).ToList();

        //find if the user already has a basket or not and store it in memory using ToList()
        var usersBasket = db.BasketLines.Where(b => b.BasketID == userName).ToList();

        //if the user has a basket then add the current items to it
        if (usersBasket != null)
        {
            //set the basketID to the username
            string prevID = BasketID;
            BasketID = userName;
            //add the lines in anonymous basket to the user's basket
            foreach (var line in basket)
            {
                AddServiceToBasket(line.ServiceID, line.Quantity);
                AddPartToBasket(line.PartId, line.Quantity);
            }
            //delete the lines in the anonymous basket from the database
            BasketID = prevID;
            EmptyBasket();
        }
        else
        {
            //if the user does not have a basket then just migrate this one
            foreach (var basketLine in basket)
            {
                basketLine.BasketID = userName;
            }

            db.SaveChanges();
        }
        HttpContext.Current.Session[BasketSessionKey] = userName;
    }

    public decimal CreateOrderLines(int orderID)
    {
        decimal orderTotal = 0;

        var basketLines = GetBasketLines();

        foreach (var item in basketLines)
        {
            BillLine BillLine = new BillLine
            {
                Service = item.Service,
                ServiceID = item.ServiceID,
                ServiceName = item.Service.Name,
                Quantity = item.Quantity,
                ServicePrice = item.Service.Price,
                BillID = orderID
            };

            orderTotal += (item.Quantity * item.Service.Price);
            db.BillLines.Add(BillLine);
        }

        db.SaveChanges();
        EmptyBasket();
        return orderTotal;
    }
}

篮子线

public class BasketLine
{
    public int ID { get; set; }
    public string BasketID { get; set; }
    public int ServiceID { get; set; }
    public int PartId { get; set; }
    [Range(0, 50, ErrorMessage = "Please enter a quantity between 0 and 50")]
    public int Quantity { get; set; }
    public DateTime DateCreated { get; set; }
    public virtual Service Service { get; set; }
    public virtual Part Part { get; set; }
}

标签: asp.net-mvc-5

解决方案


假设使用 EF Code First,异常消息表明您在BasketLines表中使用了引用PartId主键列的表内的外键约束,并且您试图在此语句中将Parts值插入到表BasketLines.PartId中不存在的列中:Parts

basketLine = new BasketLine
{
    PartId = partID, // this assignment is the problem source
    BasketID = BasketID,
    Quantity = quantity,
    DateCreated = DateTime.Now
};
db.BasketLines.Add(basketLine);

Service根据检查,您正在尝试在,Part和实体之间建立关系BasketLine,因此我建议在实体中添加ForeignKeyAttributeforServiceIdPartId属性BasketLine

public class BasketLine
{
    public int ID { get; set; }
    public string BasketID { get; set; }

    [ForeignKey("Service")]
    public int ServiceID { get; set; }

    [ForeignKey("Part")]
    public int PartId { get; set; }

    [Range(0, 50, ErrorMessage = "Please enter a quantity between 0 and 50")]
    public int Quantity { get; set; }
    public DateTime DateCreated { get; set; }
    public virtual Service Service { get; set; }
    public virtual Part Part { get; set; }
}

此外,由于声明 a BasketLinerequires Servicewith optional Part,您也可以尝试像这样修改OnModelCreating()内部方法DbContext

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
     modelBuilder.Entity<BasketLine>()
                 .HasOptional(x => x.Part) // can save BasketLine without specifying Part
                 .WithRequired(x => x.Service); // cannot save BasketLine without using Service
}

相关问题:

在 EF Code First 中配置一对一关系

INSERT 语句与 FOREIGN KEY 约束冲突


推荐阅读