Search code examples
c#asp.net-mvcentity-frameworkcode-first

trying to add one entity, but also insert another entity to db


I have three entities: Product, Item(consist of one product and no. of product that is purchased by customer) and Factor as below:

public class Factor
{
    [Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public virtual int FactorId { get; set; }
    [Required]
    public virtual System.Guid TrackingCode { set; get; }
    [StringLength(1000)]
    public string StatusOfFactor { set; get; }
    [Required, DataType(DataType.EmailAddress), StringLength(200)]
    public string EmailOfFactor { set; get; }
    // price before discount
    public virtual double PriceOfFactor { set; get; }
    public virtual double DiscountOfFactor { set; get; }
    [StringLength(3000,MinimumLength =0)]
    public virtual string GeneralDescription { set; get; }
    public virtual List<Item> Items { set; get; }
}


public class Item
{
    //[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ItemId { set; get; }
    public int Count { set; get; }
    // 1 -> 1 relationship between product and Item
    public virtual Product Product { set; get; }
    // * -> * relationship between Item and Factor
    public virtual List<Factor> Factors { set; get; }
}


public class Product
{
    [Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public virtual int ProductId { set; get; }
    [Required]
    [StringLength(128)]
    public virtual string NameFa { set; get; }
    [Required]
    [Range(0, 990000000)]
    public virtual double Price { set; get; }
    // many->many relationship category and product
    public virtual List<Category> Categories { set; get; }
    //public virtual List<Factor> Factors { get; set; }
    public virtual Item Item { set; get; }
}

the relationship between entities are as follow: 1 -> 1 in Product-Item and * -> * in Item-Factor

public class ProductConfig:EntityTypeConfiguration<Product>
{
    public ProductConfig() {
        // one to one relationship between product and item
        HasOptional(p => p.Item).WithRequired(i => i.Product);
    }
}

and

public class FactorConfig : EntityTypeConfiguration<Factor>
{
    public FactorConfig( ) {
       HasMany(p => p.Items)
      .WithMany(p => p.Factors)
      .Map(c => {
          c.ToTable("ItemsFactors");
          c.MapLeftKey("FactorID");
          c.MapRightKey("ItemID");
      });
    }
}

when i Insert a factor to db, another product also add to table of product!!! here is a code for inserting factor to db:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult RegisterFactor( [Bind(Include = "FactorId,TrackingCode,RegistrationDate,PaymentSucceed,PaymentIdOfBank,PaymentDate,StatusOfFactor,EmailOfFactor,TranmissionSucceed,TransmissionDate,PriceOfFactor,DiscountOfFactor,GeneralDescription,IsReturned,ReturnedDate,ReturnedDescription")]Factor factor )  
{  
    {
        // Session consist of Items and Items consist of Products
        List<Item> purchasedItems =
        (List<Item>)Session[Constants.SHOPPINGBAG];
        double totalPriceBeforeDiscount = 0.0d; 
        double totalDiscount = 0.0d;            
        double totalPriceAfterDiscount = 0.0; 
        //
        Guid trackingCode = Guid.NewGuid();
        factor.Items = new List<Item>();
        if ( purchasedItems == null )
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        foreach ( Item item in purchasedItems )
        {
            if ( item.Product != null )
            {
                factor.Items.Add(item);
            }
        }
        // allocate data to factor
        factor.PriceOfFactor = totalPriceBeforeDiscount;
        factor.DiscountOfFactor = totalDiscount;
        factor.PaymentDate = DateTime.Now;
        factor.RegistrationDate = DateTime.Now;
        factor.TrackingCode = trackingCode;
        if ( ModelState.IsValid )
        {
            //db.Factors.AsNoTracking();
            db.Products.AsNoTracking();
            db.Factors.Add(factor);
            db.SaveChanges();
            EmptyShoppingCart();
            return View("RegisterFactorSucceed", factor);
        }
        return View(factor);
    }
}

It is really awkward (for me). why was happening?


Solution

  • Your 'ProductConfig' is saying whenever Item has 'product' then the same should be added into Product table. Here is the modified code.

    ProductConfig class

    public class ProductConfig : EntityTypeConfiguration<Product>
    {
        public ProductConfig()
        {
            // one to one relationship between product and item
            HasOptional(p => p.Item).WithOptionalDependent(i => i.Product);
        }
    }
    

    If you change Item.Product to null then it won't add to Product table.

    foreach (Item item in purchasedItems)
            {
                if (item.Product != null)
                {
                    factor.Items.Add(item);
                    item.Product = null;//Setting Product to null
                }
            }