Reputation: 1161
I have a problem with Entity Framework.... I don't know it well.
I am working on a seemingly simple task of associating an existing contact to a new order in a system I'm working on. Contacts will always exist prior to being associated to the order.
Simplified database tables...
Order
OrderID
Status
Created
Contact
ContactID
FirstName
LastName
ContactToOrderMap
OrderID
ContactID
I've linked these two tables in the DbContext.
modelBuilder.Entity<Order>()
.HasMany<Contact>(a => a.Contacts)
.WithMany()
.Map(a =>
{
a.ToTable("ContactToOrderMap");
a.MapLeftKey("OrderID");
a.MapRightKey("ContactID");
});
I wrote a unit test that simply creates an order, a contact, adds the contact to a list member on the order and attempts to save.
// setup
var order = new Order() { // initialize required fields };
// add a contact that already exists in the database
var orderContact = new Contact() { ID = 2 };
order.Contacts.Add(orderContact);
// call
logic.Save(ref order);
Eventually this order is saved after some unrelated business logic is performed...
// Add to collection
_db.Orders.Add(obj);
// Commit changes
_db.SaveChanges();
>> Here I receive errors related to required database fields on the Contact table. Not what I'm looking for as I really just want to add an association record in the ContactToOrderMap table.
As a next step, I tried to retrieve the existing contacts from the database prior to saving the order. This code's not super clean, but it should explain what I'm attempting.
if (currentOrder.Contacts != null)
{
var matchedContacts = new List<Contact>();
foreach (var con in currentOrder.Contacts)
{
matchedContacts.Add(_contactLogic.Get(con.ID));
}
currentOrder.Contacts.Clear();
foreach (var item in matchedContacts)
{
currentOrder.Contacts.Add(item);
}
}
This created the association, but created a new Contact (new unique ID) as well.
The goal is to create an association and a new order only, not create a new contact.
Any ideas or pointers to get me going in the right direction?
Please let me know if additional information is required.
Edit: Fixed code - renamed obj to currentOrder.
Upvotes: 2
Views: 832
Reputation: 109136
After the line
var orderContact = new Contact() { ID = 2 };
do
_db.Contacts.Attach(orderContact);
Now the contact is part of the context in an Unchanged
state, and
order.Contacts.Add(orderContact);
will not change its state to Added
anymore.
Upvotes: 3