haydnD
haydnD

Reputation: 2293

entity framework saves first item in the loop but none other

In my controller I'm looping through items and saving them to my db. The problem is that it saves the first item, but none of the others. I put a breakpoint on the "SaveItem()" line in the loop and it hits it every time, but what seems odd to me is that it only goes through to the method for the 1st item.

What am I doing wrong?

public void SubmitItem(Cart cart, ShippingDetails shippingDetails, ProcessedItems processedItem, string orderID)
{
    var cartItems = cart.Lines;
    //CartIndexViewModel cartIndex = new CartIndexViewModel();
    //var customID = cartIndex.OrderID;

    foreach(var item in cartItems)
    {
        processedItem.OrderID = orderID;
        processedItem.ProductID = item.Product.ProductID;
        processedItem.Name = item.Product.Name;
        processedItem.Description = item.Product.Description;
        processedItem.Price = item.Product.Price;
        processedItem.Category = item.Product.Category;
        processedItem.ImageName = item.Product.ImageName;
        processedItem.Image2Name = item.Product.Image2Name;
        processedItem.Image3Name = item.Product.Image3Name;

        processedItem.BuyerName = shippingDetails.Name;
        processedItem.Line1 = shippingDetails.Line1;
        processedItem.Line2 = shippingDetails.Line2;
        processedItem.Line3 = shippingDetails.Line3;
        processedItem.City = shippingDetails.City;
        processedItem.State = shippingDetails.State;
        processedItem.Zip = shippingDetails.Zip;
        processedItem.Country = shippingDetails.Country;

        processedItem.Status = "Submitted";

        processedItems.SaveItem(processedItem);

    } 

}


    public class EFProcessedItemsRepository : IProcessedItems
{
    private  EFDbContext context = new EFDbContext();

    public IQueryable<ProcessedItems> ProcessedItem
    {
        get { return context.ProcessedItems; }
    }

    public void SaveItem(ProcessedItems processedItem)
    {
        if(processedItem.ProcessedID == 0)
        {
            try
            {
                context.ProcessedItems.Add(processedItem);

                context.SaveChanges();
            }
            catch (Exception)
            {

                throw;
            }

        }
        else
        {
            context.Entry(processedItem).State = EntityState.Modified;

        }
    }

    public void DeleteItem(ProcessedItems processedItem)
    {
        context.ProcessedItems.Remove(processedItem);
        context.SaveChanges();
    }
}

here is the class for the processedItem:

public class ProcessedItems
{
    [Key]
    public int ProcessedID { get; set; }

    public string OrderID { get; set; }
    public int ProductID { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public decimal Price { get; set; }
    public string Category { get; set; }
    public string ImageName { get; set; }
    public string Image2Name { get; set; }
    public string Image3Name { get; set; }
    public string Status { get; set; }

    //shipping
    public string BuyerName { get; set; }
    public string Line1 { get; set; }
    public string Line2 { get; set; }
    public string Line3 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
    public string Country { get; set; }


}

Interface:

public interface IProcessedItems
{
    IQueryable<ProcessedItems> ProcessedItem { get; }
    void SaveItem(ProcessedItems processedItem);
    void DeleteItem(ProcessedItems processedItem);
}

Upvotes: 2

Views: 1310

Answers (3)

user554180
user554180

Reputation:

try calling context.SaveChanges() after adding all of the items, I think it should persist them all in one go.

Another thing to try:

Refactor your code so that SaveItem accepts only one item to save, Add it and call SaveChanges()

Loop through the cart items outside the method and call the method with one item to save at a time.

// set orderID, shippingDetails above

foreach(var item in cartItems)
{
    ProcessedItems processedItem = new ProcessedItems();
    processedItem.OrderID = orderID;
    processedItem.ProductID = item.Product.ProductID;
    processedItem.Name = item.Product.Name;
    processedItem.Description = item.Product.Description;
    processedItem.Price = item.Product.Price;
    processedItem.Category = item.Product.Category;
    processedItem.ImageName = item.Product.ImageName;
    processedItem.Image2Name = item.Product.Image2Name;
    processedItem.Image3Name = item.Product.Image3Name;

    processedItem.BuyerName = shippingDetails.Name;
    processedItem.Line1 = shippingDetails.Line1;
    processedItem.Line2 = shippingDetails.Line2;
    processedItem.Line3 = shippingDetails.Line3;
    processedItem.City = shippingDetails.City;
    processedItem.State = shippingDetails.State;
    processedItem.Zip = shippingDetails.Zip;
    processedItem.Country = shippingDetails.Country;
    SubmitItem(processedItem);

}

public void SubmitItem(ProcessedItems processedItem)
{
    processedItem.Status = "Submitted";
    processedItems.SaveItem(processedItem);
}

Upvotes: 3

Justin Harvey
Justin Harvey

Reputation: 14682

I think it is because processedItem is the same instance for each loop iteration. So after it has been through SaveItem once, it has its ProcessedID set and therefore won't get processed again.

Upvotes: 1

Ilya Ivanov
Ilya Ivanov

Reputation: 23636

My first guess is that you always store one entity, which is stored in processedItem, which is a input parameter. Try to create new Entity on each loop and then save it. In other words, you assign values to input parameter

processedItem.OrderID = orderID; 

and then store same entity each time, but with changed fields

processedItems.SaveItem(processedItem);

Upvotes: 0

Related Questions