Insert entity with one related entity which existed in the database

Multi tool use
Insert entity with one related entity which existed in the database
I am stuck at the operation when using Entity Framework Core 2 to perform an insert of a new entity with one related entity which already existed in the database. For example, I have two objects with one to many relationship:
public Class OrderDetail
{
public int ParentID {get;set;}
public string OrderDetailName {get;set;}
public int ProductID {get;set;}
public virtual Product ProductFK {get;set;}
}
public Class Product
{
public int ProductID {get;set;}
public string ProductName {get;set;}
public virtual Collection<OrderDetail> OrderDetails {get;set;} = new Collection<OrderDetail>();
}
I would like to add a new OrderDetail
with an existing Product
(with productID = 3
) into the database, so I perform like:
OrderDetail
Product
productID = 3
private void AddOrderDetail(int productID)
{
OrderDetail newOrderDetail = new OrderDetail();
newOrderDetail.Name = "New OrderDetail";
// Here I have no clue what would be the correct way...Should I do
// Approach A(pick related entity from database then assign as related entity to base entity):
var ProductFromDB = DbContext.Products.SingleOrDefault(p => p.ProductID == productID);
newOrderDetail.ProductFK = ProductFromDB;
// Approach B(directly assign the foreign key value to base entity)
newOrderDetail.ProductID = productID
DbContext.SaveChange();
}
By using approach (A), my newOrderDetail
failed to save and I looked into SQL resource, looks like it considered the one that I retrieved from the database (ProductFromDB
) as a new object and was trying to insert it again. I feel it's redundant job for picking ProductFromDB
first then assign to the inserted entity...
newOrderDetail
ProductFromDB
ProductFromDB
By using approach (B), my newOrderDetail
still failed to save, and I am getting an exception like "insert A second operation started on this context before a previous operation completed. Any instance members are not guaranteed to be thread safe.", however, this exception does not happen constantly. I looked into the SQL and found the SQL Script, by running it individually in SQL Server it worked, however when running an application side, it's not working...
newOrderDetail
So what would be the correct way to deal with above scenario?
1 Answer
1
If you don't need access to the complete Product
object right away, you could try to set just the foreign key column value of your newOrderDetail
. Also, you need to ADD your newly created OrderDetail
object to the DbContext
before saving - something like this:
Product
newOrderDetail
OrderDetail
DbContext
private void AddOrderDetail(int productID)
{
OrderDetail newOrderDetail = new OrderDetail();
newOrderDetail.Name = "New OrderDetail";
newOrderDetail.ProductID = productID
// OF COURSE, you need to ADD the newly created object to the context!
DbContext.OrderDetails.Add(newOrderDetail);
DbContext.SaveChange();
}
Next time around, when you actually fetch the OrderDetail
, it will resolve the linked product and you should be fine.:
OrderDetail
using (var DbContext = new YourDbContext())
{
OrderDetail od = DbContext.OrderDetails.FirstOrDefault(x => x.Name = "New OrderDetail");
....
}
So what if I want to save a new Product with a collection of existed OrderDetails, from API I can get a list of OrderDetailID in an array, should I need to fetch each OrderDetail from database (by OrderDetailID) then add to the Product's OrderDetails Collection? I am not sure that's the correct way but seems like it drops a lot of performance...
– Kevin Ding
Jun 30 at 8:36
@KevinDing: seems like a highly unlikely business scenario - adding a new product to a list of existing orders...... is this just for the sake of discussion, or do you actually have such a business case?? But yes - if you ever need to grab a whole collection to store - of course that will be slower than storing just a single object - no doubt about it.
– marc_s
Jun 30 at 9:51
thank you so much! Sorry If I did not describe correctly, this time I was trying to save a single object but it has a collection of its related entities which are already existed in the database, I have opened a new ticket on that [Entity Framework Core - insert entity with multiple related entities which existed in the database][1] [1]: stackoverflow.com/questions/51120596/…
– Kevin Ding
Jul 1 at 5:33
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!
– Kevin Ding
Jun 30 at 8:30