Insert entity with many to many related entities which exist in the database

Multi tool use
Insert entity with many to many related entities which exist in the database
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?
1 Answer
1
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:
Order
Product
OrderProduct
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.
SaveChanges
@KevinDing Yes, my bad, I should have deleted that
OrderId
property. And yes, you need to define OrderProduct
since a many-to-many relationship is not actually logical and can only be modeled as two one-to-many relationships.– Camilo Terevinto
Jul 2 at 0:43
OrderId
OrderProduct
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Thank you so much for your answer! I know where I make mistakes now! However, I have that mapping table in database, by using your way, do I still need to define the OrderProduct class in C#? In addition, there is a 'Order ID' in Product class, I guess that should also be removed, right?
– Kevin Ding
Jul 2 at 0:41