How to update the many to many navigation property?
I want to update the entity I get an error
have the same primary key value
I know there is way to split the many-many relation to two many-to-one relations, but this is the case. Update many-many relation.
I do this way to add new a entity with navigation property without problem BUT for updating there is an error. I tried to remove db.Entry(item).State = ...
in update, but the problem is still there.
public class TrendChart
{
public int Id { get; set; }
public string Name { get; set; }
public virtual List<ParameterMonitor> Monitors { get; set; }
}
public class ParameterMonitor
{
public int Id { get; set; }
public virtual List<TrendChart> Charts{ get; set; }
}
var db = new DataAccess.ApplicationDbContext();
var newTrendChart = db.TrendChart.Where(x => x.Id == trendChart.Id).FirstOrDefault();
if (newTrendChart != null)
{
if (newTrendChart.Monitors != null)
newTrendChart.Monitors.Clear();
newTrendChart.Name = trendChart.Name;
newTrendChart.Monitors = new List<ParameterMonitor>();
foreach (var item in trendChart.Monitors)
{
newTrendChart.Monitors.Add(new DataAccess.ParameterMonitor { MOParameterId = item.MoParameterId });
}
// prevent from adding new parameter
foreach (var item in newTrendChart.Monitors)
{
// here the ERROR happens
db.Entry(item).StateSystem.Data.Entity.EntityState.Unchanged;
}
db.SaveChanges();
}
I found the solution, the point is that whenever you try to add something in intermediate table the CLEAR() function does not remove the history of items in the behind scene which we do not see, consider there are two items in the intermediate table , 1,2 and 1,3 . if you want to update the table by just 1,2 , it means the clear function remove 1,2 and 1,3 and again add 1,2. but it does not work because there is already an item 1,2 in behind scene. we need to remove() 1,3 and don't care about 1,2. Is there any other Solution.
var tempMOList = new List<int>();
tempMOList = newTrendChart.Monitors.Select(x=> x.MOParameterId).ToList();
foreach (var id in tempMOList)
{
var temp = newTrendChart.Monitors.Where(x => x.MOParameterId == id).FirstOrDefault();
if (trendChart.Monitors.Any(x => x.MoParameterId == id) == false)
newTrendChart.Monitors.Remove(temp);
}
foreach (var item in trendChart.Monitors)
{
if (newTrendChart.Monitors.Any(x => x.MOParameterId == item.MoParameterId) == false)
newTrendChart.Monitors.Add(new DataAccess.ParameterMonitor { MOParameterId = item.MoParameterId });
}
//prevent from adding new parameter
foreach (var item in newTrendChart.Monitors)
{
db.Entry(item).State = System.Data.Entity.EntityState.Unchanged;
}
db.SaveChanges();