实体框架多对多关系更新

时间:2018-01-21 06:12:54

标签: c# entity-framework navigation-properties

如何更新多对多的导航属性?

我想更新我收到错误的实体

  

具有相同的主键值

我知道有办法将多对多关系分成两个多对一关系,但事实就是如此。更新很多关系。

我这样做是为了添加具有导航属性的新实体而没有问题但是为了更新存在错误。我尝试在更新中删除db.Entry(item).State = ...,但问题仍然存在。

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();
}

1 个答案:

答案 0 :(得分:1)

我找到了解决方案,重点是每当你尝试在中间表中添加一些东西时,CLEAR()函数不会删除后面场景中我们看不到的项目的历史记录,考虑到有两个项目中间表,1,2和1,3。如果你想仅用1,2更新表,则意味着clear函数删除1,2和1,3并再次添加1,2。但它不起作用,因为幕后已有一个项目1,2。我们需要删除()1,3并且不关心1,2。还有其他解决方案。

  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();
相关问题