Добавление нескольких классов в корзину классов .net MVC 5 - PullRequest
0 голосов
/ 28 февраля 2019

Я пытаюсь придумать приложение для бронирования в автосервисе, которое позволяет либо забронировать автомобиль в сервис, либо купить несколько запчастей, что не является обязательным, но я получаю ошибку, которая гласит следующее:

SqlException: оператор INSERT конфликтовал с ограничением FOREIGN KEY "FK_dbo.BasketLines_dbo.Parts_PartID".Конфликт произошел в базе данных «aspnet-Noir-20190224082924», таблица «dbo.Parts», столбец «PartId».Оператор был прерван.

Мои классы следующие:

PART

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; }
}

ServicePartMapping

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;
    }
}

BasketLine

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; }
}

1 Ответ

0 голосов
/ 01 марта 2019

Предполагается, что 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сущности, поэтому я предложил добавить ForeignKeyAttribute для ServiceId и PartId свойство в 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; }
}

Дополнительно, поскольку указано, что для BasketLine требуется Service с необязательным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Первый код

Оператор INSERT противоречит ограничению FOREIGN KEY

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...