Failed to determine the main end of the etaxiDataModel relationship. Multiple objects added may have the same primary key.

Mapping definitions for SettlementShift I’ve been struggling with this problem for some time and can’t solve it. I read a few posts and tried several different solutions, but nothing worked. Now I feel like I am stopped and really need help.

I am using EF 5+ with DB and the first edmx file. I have 3 different tables in my database: 1. Calculation 2. Cost 3. Shift

Settlement has a Cost and Shift collection (with a link) associated with the Association in my edmx file.

Settlement table with Link tables in my DB I need to insert a new setting into my db with reference to the existing Cost and Shift collections. The shifts and costs included in my settlement object, which I am trying to insert, contain all the data associated with it, and none of them changes in any way (just as I got from db). Here in my method of inserting an object into my db.

public bool CreateSettlement(Settlement settlement) { bool _success; var _context = new EtaxiEnteties();// ObjectFactory.Get<IETaxiEntitiesContext>(); try { var _newSettlement = new Settlement { CreateDate = settlement.CreateDate, Driver = settlement.Driver, DriverID = settlement.DriverID, Car = settlement.Car, CarID = settlement.CarID, DocPath = settlement.DocPath }; foreach (var _shift in settlement.Shifts) { //var _sh = _context.Shifts.Find(_shift.ShiftID); //_context.Entry(_sh).CurrentValues.SetValues(_shift); _newSettlement.Shifts.Add(_shift); } foreach (var _cost in settlement.Costs) { ////var _sh = _context.Costs.Find(_cost.CostID); ////_context.Entry(_sh).CurrentValues.SetValues(_cost); _newSettlement.Costs.Add(_cost); } _context.Settlements.Add(_newSettlement); _success = _context.SaveChanges() > 0; } catch (Exception ex) { throw new Exception(ex.Message); } return _success; } 

Any help on this would be greatly appreciated.

This is how I add Cost and Shift to my collection:

I create a settlement on the page:

 _settlement = new Settlement { CreateDate = DateTime.Now, Driver = _driver, DriverID = _driver.DriverID, Car = _car, CarID = _car.CarID, DocPath = _path }; 

then when I create a PDF file with selected lines from 2 separated grid views:

  foreach (GridDataItem _selectedRow in gwShifts.MasterTableView.Items) { if (_selectedRow.Selected) { var _shift = _diaryRepository.GetShiftByID((int) _selectedRow.GetDataKeyValue("ShiftID")).FirstOrDefault(); if (_shift != null) { _settlement.Shifts.Add(_shift); _settlementData.Shifts.Add(_shift); _settlementData.SplitPercentace = GetTemplateValue(_selectedRow, "lblSplit"); _settlementData.SettlementAmount = GetTemplateValue(_selectedRow, "lblSettlementAmount"); if (_settlementData.Shifts != null) { _tableShifts.AddCell( new PdfPCell( new Phrase( _settlementData.Shifts.FirstOrDefault().ShiftDate.ToShortDateString(), _bodyFont)) {Border = 0}); _tableShifts.AddCell( new PdfPCell( new Phrase( string.Format("{0:c}", _settlementData.Shifts.FirstOrDefault().GrossAmount), _bodyFont)) {Border = 0}); _tableShifts.AddCell( new PdfPCell( new Phrase( string.Format("{0:c}", _settlementData.Shifts.FirstOrDefault().MoneyAmount), _bodyFont)) {Border = 0}); _tableShifts.AddCell(new PdfPCell(new Phrase(_settlementData.SplitPercentace, _bodyFont)) {Border = 0}); _tableShifts.AddCell( new PdfPCell(new Phrase(_settlementData.SettlementAmount, _boldTableFont)) {Border = 0}); _totalAmount.AddRange(new[] { Convert.ToInt32( _settlementData.SettlementAmount.Replace(".", ""). Replace(",", "").Replace("kr", "")) }); _settlementData.Shifts.Remove(_shift); } } } } var _summaryCell = new PdfPCell(new Phrase("Upphæð: " + string.Format("{0:c}", _totalAmount.Sum()), _boldTableFont)) { Border = 0, Colspan = 5, HorizontalAlignment = Element.ALIGN_RIGHT, Padding = 5, BorderWidthTop = 1 }; _tableShifts.AddCell(_summaryCell); if (_totalAmount.Count != 0) _totalAmount.Clear(); } 

there you see how I add Shift to this calculation object:

  var _shift = _diaryRepository.GetShiftByID((int) _selectedRow.GetDataKeyValue("ShiftID")).FirstOrDefault(); if (_shift != null) { _settlement.Shifts.Add(_shift); 

then I send this to the repository (see method above)

  if(_driverRepository.CreateSettlement(_settlement)) { SetMessage("Uppgjör hefur verið skapað og sent bílstjóra ef e-póstur er skráður á viðkomandi bílstjóra.", "Uppgjör skapað"); pnlSettlement.Visible = false; pnlDocCreation.Visible = false; pnlResult.Visible = false; } 

I also tried just adding the param parameter directly to the context, but got a similar error.

+4
source share
3 answers

OK, came up with an "ugly" solution on this ... but it is resolved. Changed the relationship "Model" to one (calculated) → a lot (shift or cost).

I create a new settlement and save it in the database. Extract each Shift and Cost from the SettlementID DB update for each and save them to the database.

  try { var _newSettlement = new Settlement { CreateDate = settlement.CreateDate, DriverID = settlement.DriverID, CarID = settlement.CarID, DocPath = settlement.DocPath }; Add(_newSettlement); _success = SaveWithSuccess() > 0; var _settlement = GetAll().FirstOrDefault(x => x.SettlementID == _newSettlement.SettlementID); if (_success) { foreach (var _shift in settlement.Shifts) { var _sh = _diaryRepository.GetShiftByID(_shift.ShiftID).FirstOrDefault(); _sh.SettlementID = _settlement.SettlementID; _diaryRepository.UpdateShift(_sh); } foreach (var _cost in settlement.Costs) { var _ch = _costRepository.GetCostByID(_cost.CostID); _ch.SettlementID = _settlement.SettlementID; _costRepository.UpdateCost(_ch); } } } 

not very beautiful, but it solves the problem. I am not worried about loading the DB query ... in this case it will not be so high.

I would have thought that there is a better solution for this, but I could not find it at this time.

Thanks for all your efforts to help :)

0
source

I think this is due to the way you fill out the Shifts and Costs collection. You are trying to add already created records (i.e. already set your primary key values) for saving with a new Settlement object, but I believe that the Entity Framework is not trying to create new ones that are associated with your new Settlement object, but rather save them in table as is. In this case, you really will have a situation where several objects have the same primary key.

I would try the following (I will only show you the Shifts , but you can also apply it to the Costs loop):

 foreach (var _shift in settlement.Shifts) { var newShift = new Shift { /*Copy all of the values from _shift here*/ }; _newSettlement.Shifts.Add(_shift); context.Shifts.Add(newShift); } 

If this does not work, I suggest debugging Costs and Shifts to make sure that you do not have duplicates in these collections.

0
source

If you do not need new Shifts and Costs , then I can only assume that you need to transfer the existing ones to the new Settlement

 foreach (var shift in settlement.Shifts) { //either shift.Settlement = newSettlement; //or shift.SettlementId = newSettlement.SettlementId; //depending on your object model } 

I just realized that I misunderstood this question. There are two additional tables not shown in the diagram (Costs and Shifts). The problem is creating the SettlementCost and SettlementShift objects that connect the Settlement to Costs\Shifts .

0
source

All Articles