2015-09-09 74 views
0

插入正常。更新不适用于收藏。并且不要给出任何错误。我究竟做错了什么? 在代码中有对规则的简要说明。实体框架 - 编辑复杂实体时遇到问题

 public void EditaModelo(Modelo model) 
      { 
       try 
       { 
        // ProjectResponsible - is an unmapped property. It was used to separate ModeloFuncao between type 2 and type 1 (ProjectResponsible and ProductDevelopment) 
              // ModeloFuncao is a collection within a model where for each function there is a responsibility within the model. 
              // In other words, for each record in the function table shows a field on the screen. The same goes for ProductDevelopment. 
              // When you save the model, there will be incusões, deletions and changes of those responsible. 
              // The IsUpdate property tells whether the record already exists and will be changed. 
        var ModelosToAdd = model.ProjectResponsible.Where(x => !String.IsNullOrWhiteSpace(x.Usuario) && !x.IsUpdate).ToList(); 
        List<ModeloFuncao> ModelosToRemove = model.ProjectResponsible.Where(x => String.IsNullOrWhiteSpace(x.Usuario) && x.IsUpdate).ToList(); 
        List<ModeloFuncao> ModelosToUpdate = model.ProjectResponsible.Where(x => !String.IsNullOrWhiteSpace(x.Usuario) && x.IsUpdate).ToList(); 

        ModelosToAdd.AddRange(model.ProductDevelopment.Where(x => !String.IsNullOrWhiteSpace(x.Usuario) && !x.IsUpdate).ToList()); 
        ModelosToRemove.AddRange(model.ProductDevelopment.Where(x => String.IsNullOrWhiteSpace(x.Usuario) && x.IsUpdate).ToList()); 
        ModelosToUpdate.AddRange(model.ProductDevelopment.Where(x => !String.IsNullOrWhiteSpace(x.Usuario) && x.IsUpdate).ToList()); 

        if(ModelosToAdd.Count > 0) context.ModelosFuncoes.AddRange(ModelosToAdd); //Insert is Ok 
        if (ModelosToRemove.Count > 0) context.ModelosFuncoes.RemoveRange(ModelosToRemove); //Not tested 
        if (ModelosToUpdate.Count > 0) ModelosToUpdate.ForEach(x => context.ModelosFuncoes.Attach(x)); //Not working 

        // The ModeloPlanta is a collection in the model table and follow the rules as explained below in ModeloPlantaArea. 
        List<ModeloPlanta> plantasToUpdate = model.ModelosPlantas.ToList(); 
        plantasToUpdate.ForEach(x => context.ModelosPlantas.Attach(x));//Not working 

      // The ModeloPlantaArea is a collection in the model table. Each model has a number of plants and each plant has a number of areas. 
      // Each plant has a responsibility and each area has a responsibility. 
      // The screen should display a field for each plant x Responsible and for each Area x Responsible 
      // When you save the model, there will be incusões, deletions and changes of those responsible. 
        List<ModeloPlantaArea> AreasToAdd = model.PlantasArea.Where(x => !String.IsNullOrWhiteSpace(x.UsuarioResponsavel) && !x.IsUpdate).ToList(); 
        List<ModeloPlantaArea> AreasToUpdate = model.PlantasArea.Where(x => !String.IsNullOrWhiteSpace(x.UsuarioResponsavel) && x.IsUpdate).ToList(); 
        List<ModeloPlantaArea> AreasToRemove = model.PlantasArea.Where(x => String.IsNullOrWhiteSpace(x.UsuarioResponsavel) && x.IsUpdate).ToList(); 

        if (AreasToAdd.Count > 0) context.ModelosPlantasArea.AddRange(AreasToAdd);//Insert is Ok 
        if (AreasToUpdate.Count > 0) AreasToUpdate.ForEach(x => context.ModelosPlantasArea.Attach(x));//Not working 
        if (AreasToRemove.Count > 0) context.ModelosPlantasArea.RemoveRange(AreasToRemove);//Not tested 

       // When saving Model, need to save (add, delete, change) collections. And if a collection fails, the other must not be saved. 
                 // So far this Inclusion OK. The change is not working.     

        this.Update(model);   
       } 
       catch (Exception ex) 
       { 
        throw ex; 
       } 

      } 

更新方法:

public void Update(Modelo item, IEnumerable<string> fieldsToUpdate = null) 
{ 
    base.context.Modelos.Attach(item); 

    base.UpdateSave(item, fieldsToUpdate); 
} 

UpdateSave方法:

protected void UpdateSave<TEntity>(TEntity item, IEnumerable<string> fieldsToUpdate) where TEntity : class 
{ 
    var entry = this.context.Entry<TEntity>(item); 
    if (fieldsToUpdate == null || fieldsToUpdate.Count() == 0) 
     entry.State = System.Data.Entity.EntityState.Modified; 
    else 
    { 
     this.changeFieldsModified<TEntity>(entry, fieldsToUpdate); 
    } 
    this.Save(); 
} 

保存方法:

protected void Save(bool auditing = true) 
{ 
    try 
    { 
     this.context.SaveChanges(auditing); 
    } 
    catch (DbEntityValidationException exception) 
    { 
     throw new ValidationException(exception); 
    } 
    catch 
    { 
     throw; 
    } 
} 

SaveChanges方法:

public int SaveChanges(bool auditing) 
{ 
    var entriesAdded = new List<DbEntityEntry>(); 

    // Salva o log dos itens alterados e excluídos. 
    if (auditing && base.ChangeTracker.HasChanges()) 
     foreach (var entry in base.ChangeTracker.Entries()) 
      switch (entry.State) 
      { 
       case EntityState.Added: 
        entriesAdded.Add(entry); 
        break; 
       case EntityState.Deleted: 
        this.saveEntryOperation(entry, EntityState.Deleted); 
        break; 
       case EntityState.Modified: 
        this.saveEntryOperation(entry, EntityState.Modified); 
        break; 
      } 
    // Realiza a persitência de dados 
    int count = base.SaveChanges(); 

    // Salva o log dos itens adicionados. 
    if (auditing && entriesAdded.Count > 0) 
     foreach (var entry in entriesAdded) 
      this.saveEntryOperation(entry, EntityState.Added); 

    this.AuditionContext.SaveChanges(); 
    return count; 
} 

回答

1

Attach只是将实体添加到更改跟踪中,但如果您在该点后没有实际更改它,则其状态仍为Unchanged。事实上,它与数据库中的内容已经不同了,这是没有意义的。

发出信号,表明实体需要更新,则需要将其设置为Modified

db.Entry(entity).State = EntityState.Modified; 

如果实体尚未连接,这也将有将其附着的效果,所以没有还需要拨打Attach

[编者:费雷拉] 这个技巧工作正常。我做了如下更改。

if (ModelosToUpdate.Count > 0) 
{ 
    ModelosToUpdate.ForEach(x => 
    { 
     context.ModelosFuncoes.Attach(x); 
     var entry = this.context.Entry<ModeloFuncao>(x); 
     entry.State = System.Data.Entity.EntityState.Modified 
    }); 
} 
+0

我会尝试,我会在这里张贴结果。 – Ferreira

+1

工作正常。谢谢。你拯救了我的一天。有一个疑问。我需要做这个删除呢? – Ferreira

+1

不可以。从集合中删除应该足够了。 –