使用EntityState.Modified

时间:2016-11-11 14:29:33

标签: c# entity-framework entity-framework-6

我有一个机场实体,它引用了每个实体都有自己参考的其他实体。

在尝试更新机场时,我有一些例外情况。 下面是试图更新机场的代码

var airport = context.Airports
    .Where(a => a.AirportID == airportToUpdate.AirportID).FirstOrDefault();

var ai = AirportConverter.ToModel(airportToUpdate);
ai.AirportID = airport.AirportID;
airport.IsOpenForFlights = ai.IsOpenForFlights;

airport.EmergencyLandings = new List<Scenario>();
foreach (var emergency in ai.EmergencyLandings)
{
    var sce = context.Scenarios
        .Include(s => s.Mission).Include(s => s.Planes)
        .Where(s => s.ScenarioID == emergency.ScenarioID).First();
    airport.EmergencyLandings.Add(sce);
    context.Entry(sce).State = EntityState.Modified;
}

airport.ExistingFilghtNumbers = new List<string>();
foreach (var flight in ai.ExistingFilghtNumbers)
{
    airport.ExistingFilghtNumbers.Add(flight);
    context.Entry(flight).State = EntityState.Modified;
}

var parkingLot = ai.ParkingLots.First();
var pLot = context.ParkingLots
    .Include(p => p.AtAirport)
    .Include(p => p.ParkingStations.Select(pa => pa.PlaneParking))
    .Where(p => p.ParkingLotID == parkingLot.ParkingLotID).First();
airport.ParkingLots = new List<ParkingLot>();
airport.ParkingLots.Add(pLot);
context.Entry(pLot).State = EntityState.Modified;

airport.Queues = new List<PlanesQueue>();
foreach (var queue in ai.Queues)
{
    qu = context.PlanesQueues
        .Include(p => p.Planes.Select(pl => pl.AtQueue))
        .Where(q => q.QueueNumber == queue.QueueNumber).First();
    qu.Planes = queue.Planes;
    airport.Queues.Add(qu);
    context.Entry(qu).State = EntityState.Modified;
}

airport.Routes = new List<Route>();
foreach (var route in ai.Routes)
{
    var ro = context.Routes
        .Include(r => r.PlaneOnRoute)
        .Where(r => r.RouteID == route.RouteID).First();
    airport.Routes.Add(route);
    context.Entry(route).State = EntityState.Modified;
}

//var entry = context.Entry(airport);
//entry.State = System.Data.Entity.EntityState.Modified;
context.SaveChanges();

我已经尝试过最简单的更新,直到我获得此代码。 尝试首先删除实体,然后再次添加它,并尝试在更新机场本身之前更新每个实体。

它仍然没有用,很多例外情况如

  

保存或接受更改失败,因为多个类型为&#39; FlightsControl.Dal.Entities.Route&#39;的实体具有相同的主键值。确保显式设置的主键值是唯一的。确保在数据库和Entity Framework模型中正确配置了数据库生成的主键。使用实体设计器进行数据库优先/模型优先配置。使用&#39; HasDatabaseGeneratedOption&#34;流利的API或“DatabaseGeneratedAttribute”#39;代码优先配置

当然它会有相同的主键,我试图更新它而不只是添加它..

这是机场实体

public virtual int AirportID { get; set; }
public  ICollection<PlanesQueue> Queues { get; set; }
public  ICollection<ParkingLot> ParkingLots { get; set; }
public  ICollection<Route> Routes { get; set; }
public virtual ICollection<string> ExistingFilghtNumbers { get; set; }
public virtual bool IsOpenForFlights { get; set; }
public  ICollection<Scenario> EmergencyLandings { get; set; }

机场配置

public AirportConfig()
{
    this.HasKey(a => a.AirportID);
    this.Property(a => a.AirportID)
        .HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity);
    this.HasMany(a => a.Queues).WithRequired(q => q.AtAirport);
    this.HasMany(a => a.ParkingLots).WithRequired(p => p.AtAirport);
    this.HasMany(a => a.Routes).WithRequired(r => r.AtAirport);
    this.HasMany(a => a.EmergencyLandings).WithRequired(s => s.AtAirport);
}

1 个答案:

答案 0 :(得分:0)

您正在查询路由的上下文,但是您要添加到列表并标记为已修改的路由是在循环中获取的一个实体。
尝试使用您查询的路由而不是其他路由,就像在其他所有情况下一样。像:

for (i = 0; i < 5; i++) { 
  if (pid[i] > 0) {
    int status;

    waitpid(pid[i], &status, 0);
    if (status > 0) {
      // handle a process sent exit status error
    }
  } else {
    // handle a proccess was not started
  }     
}

还有一点注意:Linq的airport.Routes = new List<Route>(); foreach (var route in ai.Routes) { var ro = context.Routes .Include(r => r.PlaneOnRoute) .First(r => r.RouteID == route.RouteID); airport.Routes.Add(ro); context.Entry(ro).State = EntityState.Modified; } 方法有一个接受谓词作为参数的版本,因此为了简洁起见,您可以编写First,就像我在代码示例中所做的那样。