I have two objects with many to many relationship:
public class Order
{
public int OrderID { get; set; }
public string OrderName { get; set; }
public virtual Collection<Product> Products { get; set; } = new Collection<Product>();
}
public class Product
{
public int ProductID { get; set; }
public string ProductName { get; set; }
public int OrderID { get; set; }
public virtual Collection<Order> Orders { get; set; } = new Collection<Order>();
}
// Mapping table
public class OrderProduct
{
public int OrderId { get; set; }
public Order Order { get; set; }
public int ProductId { get; set; }
public Product Product { get; set; }
}
I would like to add a new Order with a collection of existing Products (my API would have an input of ProductID array) into the database, so I perform like:
private void AddOrder(int[] productIDs)
{
Order newOrder = new Order();
newOrder.Name = "New Order";
// Here I have no clue which would be the correct way...Should I do
// Approach A(fetch each related entity - Product from database then add them into the collection of my new base entity - Order):
productIDs.ToList().Foreach(p =>
{
newOrder.Products.Add(_dbContext.Product.FindById(p))
}
);
_dbContext.Orders.Add(newOrder);
var newOrderID = _dbContext.SaveChanges();
// then fetch each product from database and add my new Order to its collection and save
productIDs.ToList().Foreach(p =>
{
var existedProductFromDb = _dbContext.Product.FindById(p)ï¼›
existedProductFromDb.Orders.Add(newOrder);
_dbContext.SaveChanges();
}
);
}
Do I really need the Mapping table between Order and Product in Entity Framework Core? Otherwise, what would be the correct way to deal with above scenario?
Your entities do not represent a many-to-many relationship using a joined table. In fact, you don't use the joining table at all.
So, start by fixing your entities:
public class Order
{
public int OrderID {get;set;}
public string OrderName {get;set;}
public ICollection<OrderProduct> Products { get; set; } = new HashSet<OrderProduct>();
}
public class Product
{
public int ProductID {get;set;}
public string ProductName {get;set;}
public ICollection<OrderProduct> Orders { get; set; } = new HashSet<OrderProduct>();
}
A new Order
which contains many Product
s is as simple as a collection of new OrderProduct
s:
private void AddOrder(int[] productIDs)
{
Order newOrder = new Order();
newOrder.Name = "New Order";
foreach (int productId in productIDs)
{
newOrder.Products.Add(new OrderProduct { ProductId = productId });
}
_dbContext.Orders.Add(newOrder);
_dbContext.SaveChanges();
}
Also, do notice that SaveChanges
returns the number of affected rows in the database, not the Id of an inserted item.