clifford.duke
clifford.duke

Reputation: 4040

Loop Adding Records Throws Exception

Does anyone know what the proper way of adding records using loops?

I have a system that handles Inventory, Currently I need to be able to Mass Create inventory as creating 50-100 identical items with different ID's would be tedious, What I did was create a MassCreate viewmodel that would essentially take a StartID and an EndID and a base Inventory Class and in the controller loop through the difference between those two ID's and create a record

The ViewModel isn't an issue and passes the data just fine:

public class MassCreateInventoryViewModel
{
    public Inventory InventoryBase { get; set; }
    public int StartID { get; set; }
    public int EndID { get; set; }
    public IEnumerable<SelectListItem> Products { get; set; }
}

I read somewhere that the db.SaveChanges() should be outside of the loop as it should only be called once:

    for (int inventoryID = viewModel.StartID; inventoryID <= viewModel.EndID; inventoryID++)
                {
                    Inventory newInventory = new Inventory
                        {
                            InventoryID = inventoryID,
                            ProductID = viewModel.InventoryBase.ProductID,
                            DateEdited = DateTime.Now,
                            EditedByUserID = WebSecurity.CurrentUserId,
                            CustomProperties = viewModel.InventoryBase.CustomProperties
                        };

                    Database.Inventories.Add(newInventory);

                    if (newInventory.CustomProperties != null && newInventory.CustomProperties.Any())
                    {
                        foreach (CustomDataType dt in newInventory.CustomProperties.Select(x => x.DataType).ToList())
                        {
                            Database.Entry(dt).State = EntityState.Unchanged;
                        }
                    }

                }
                Database.SaveChanges();
        }

But when I try looping, it stores the first record just fine then throws a Collection was modified; enumeration operation may not execute. Exception. When I include the Database.SaveChanges() after the Add method, it throws A The property 'InventoryID' is part of the object's key information and cannot be modified. error.

The InventoryID is the Key in this table but has been set so that I can input my own ID.

[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[Display(Name = "Inventory ID")]
public new int InventoryID { get; set; }

The Custom Property is split into two models, the first being the base class.

public class CustomProperty
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int CustomPropertyID { get; set; }

    public int CustomDataTypeID { get; set; }
    [ForeignKey("CustomDataTypeID")]
    public CustomDataType DataType { get; set; }

    public string PropertyValue { get; set; }
}

and the second being the model thats mapped to the database:

[Table("CustomInventoryProperty")]
public  class CustomInventoryProperty : CustomProperty
{
    public int InventoryID { get; set; }
    [ForeignKey("InventoryID")]
    public virtual Inventory Inventory { get; set; }
}

Upvotes: 0

Views: 249

Answers (1)

ataravati
ataravati

Reputation: 9155

Replace your for loop with this:

var dateEdited = DateTime.Now;
for (int inventoryID = viewModel.StartID; inventoryID <= viewModel.EndID; inventoryID++)
{
    Inventory newInventory = new Inventory
    {
        InventoryID = inventoryID, 
        ProductID = viewModel.InventoryBase.ProductID,
        DateEdited = dateEdited,
        EditedByUserID = WebSecurity.CurrentUserId
    };

    if(viewModel.InventoryBase.CustomProperties != null)  
    {
        newInventory.CustomProperties = new List<CustomProperties>(); 
        foreach(var customProperty in viewModel.InventoryBase.CustomProperties)
        {
           newInventory.CustomProperties.Add(customProperty);
        }
    }

    Database.Inventories.Add(newInventory);
    Database.SaveChanges();
}

Upvotes: 1

Related Questions