好吧,这可能是一个我错了的概念,但无论如何...... (MVC3)我有一个带有list属性的实体。我的CRUD视图通过Ajax帖子向控制器发送JSon表示。一切都很好,除了当我发布该实体的更新时,list属性根本没有更新。实体的所有简单属性都会更新,但(正如我想象的)更新树不包括List属性。如何让EF了解列表中的这些更改?
到目前为止,这是一些代码:
[HttpPost]
public JsonResult Edit(Lote lote)
{
//Given the IDs present in lote.Documentos, load the List of Documentos
if (lote.Documentos != null)
{
List<Documento> ldoc = new List<Documento>();
foreach (var d in lote.Documentos)
{
ldoc.Add(db.Documentos.Find(d.IDDocumento));
}
lote.Documentos.Clear();
foreach (var d in ldoc)
{
lote.Documentos.Add(d);
}
}
//Now, clear all the previous errors
foreach (var modelValue in ModelState.Values)
{
modelValue.Errors.Clear();
}
//And re-validate the model
ValidateModel(lote);
if (ModelState.IsValid)
{
if (lote.IDLote > 0)
{
//Updating
db.Entry(lote).State = EntityState.Modified;
}
else
{
//Inserting
db.Lotes.Add(lote);
}
db.SaveChanges();
CustomMessages.Sucesso(TempData, "Informações salvas com sucesso.", 10000);
return Json(new { Success = 1, IDProprietario = lote.IDLote, ex = "" });
}
else
{
return Json(new { Success = 0, ex = "Falha na rotina de armazenamento das informações"});
}
这些都是班级本身:
public class Lote
{
[Key]
public int IDLote { get; set; }
(... lots of properties ...)
[Display(Name = "Documentos")]
public List<Documento> Documentos { get; set; }
}
public class Documento
{
//---=== ATRIBUTOS ===---
[Key]
public int IDDocumento { get; set; }
[Required]
[MaxLength(60)]
public string Nome { get; set; }
public List<Lote> Lotes { get; set; }
}
由于这是一个多对多的关系,我也得到了这个:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove
<System.Data.Entity.ModelConfiguration.Conventions.PluralizingTableNameConvention>();
modelBuilder.Entity<Lote>()
.HasMany(t => t.Documentos)
.WithMany(t => t.Lotes)
.Map(m =>
{
m.ToTable("LoteDocumento");
m.MapLeftKey("IDLote");
m.MapRightKey("IDDocumento");
});
(... and some other stuff)
对此有何帮助?
答案 0 :(得分:0)
尝试更改此行:
ldoc.Add(db.Documentos.Find(d.IDDocumento));
到
ldoc.Add(db.Documentos.Include("Lotes").FirstOrDefault(x => x.IDDocumento == d.IDDocumento));
您需要确保您要更改的关系/对象实际上已附加到当前的DB上下文中。否则,实体框架将无法跟踪对它们所做的更改。
This link explains it in terms of object context, but I think the same rules apply to DBcontext.
如果这不起作用,请告诉我因为我真的想要更好地理解EF的工作方式。
好的,找到了一些有用的链接:
Entity Framework and Connection Pooling
执行Include("Lotes")
时,会将与Documentos相关的抽奖添加到DBContext。实体框架现在正在跟踪这些对象。在您的代码中,您将使用此行db.Entry(lote).State = EntityState.Modified;
将其重新添加到上下文中。无论如何,这是我的猜测。
根据上面的链接,我会尝试重新编写你喜欢的内容(未编译):
[HttpPost]
public JsonResult Edit(Lote lote)
{
//get old Lote from DB
var oldLote = db.Lotes.include("Documentos").FirstOrDefault(x => x.IDLote == lote.IDLote);
//update
if(oldLote != null)
{
//refresh any other properties that you may have changed on it.
db.Entry(oldLote).CurrentValues.SetValues(lote);
//not sure if you will even need this section any more but then you can...
oldLote.Documentos.Clear();
foreach (var d in lote.Documentos)
{
oldLote.Documentos.Add(db.Documentos.include("Lotes").FirstOrDefault(x => x.IDDocumento == d.IDDocumento));
}
}
else //add
{
//not sure if this will work
foreach (var d in lote.Documentos)
{
db.Entry(d).State = EntityState.Modified;
}
db.Lotes.Add(lote);
}
//then just save changes. EF is already tracking all your objects and changes.
db.SaveChanges();
....