插入效果很好。此更新不适用于集合。并且不要给出任何错误。我究竟做错了什么? 在代码中有对规则的简要说明。
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;
}
答案 0 :(得分: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
});
}