我真的很努力将我的项目中的所有内容都与 EF 一起使用,但这确实变得越来越困难,有时它让我怀疑这是否真的是明智之举(依靠 EF 来编写数据库的所有进出)。好吧,我的问题仍然与 1-N 创建/编辑/删除功能有关(应该很简单,对吧?)。
好的,我在这里粘贴一些与我的代码等价的简单代码。
对于实体,我的主要课程为:
[Table("OLIM_LOTE")]
public class Lote
{
[Key]
[Column("LOTE_ID_LOTE")]
public int? IDLote { get; set; }
[Column("LOTE_TX_OBS")]
public string Obs {get;set;}
[Column("LOTE_TX_DOCUMENTO_EXTRA")]
public string DocumentoExtra { get; set; }
[NotMapped]
public List<DocumentoLote> Documentos { get; set; }
public void LoadLists()
{
OlimpiqueDBContext myDbContext = new OlimpiqueDBContext();
var docs = (from doc in myDbContext.DocumentosLote
where doc.IDLote == this.IDLote
select doc);
this.Documentos = docs.ToList<DocumentoLote>();
}
}
[注意我使用了可为空的 int?for Key - 否则它会抛出我验证异常,要求创建值]
对于儿童班,我得到了这个:
[Table("OLIM_DOCUMENTO_LOTE")]
public class DocumentoLote
{
[Key]
[Column("DOLO_ID_DOCUMENTO_LOTE")]
public int? IDDocumentoLote { get; set; }
[Column("DOCU_ID_DOCUMENTO")]
[ForeignKey("Documento")]
public int IDDocumento { get; set; }
public virtual Documento Documento { get; set; }
[Column("LOTE_ID_LOTE")]
[ForeignKey("Lote")]
public int IDLote { get; set; }
public virtual Lote Lote { get; set; }
}
[请注意,子类具有对所有者类的引用,它们是“IDLote”和“Lote”属性,并且所有者类具有子类实例的列表-所以我得到了双向引用-我假设这在某种程度上与问题有关]
我得到了一个由 VS2012 自动生成的控制器和视图,具有与 Lote 类相关的读/写功能。我在 View 中所做的可以描述为:我使用了一个 Jquery DataTable 来管理子类数据(用户可以在 DataTable 上添加“N”个实例)。我将 Post Button 替换为调用 JS 方法,该方法只是从 Form 和 DataTable 中获取所有数据,并将其包装在 JSon 对象中,然后通过 Ajax 将其发送到控制器。
接收它的控制器方法可以简化如下:
[HttpPost]
public JsonResult Edit(Lote lote)
{
try
{
if (ModelState.IsValid) //<< HAVING PROBLEMS HERE... DETAILS BELOW
{
if (lote.IDLote.HasValue)
{
//Separete updates/inserts from deletes
List<int?> dbDocs = db.DocumentosLote
.Where(dt => dt.IDLote == lote.IDLote)
.Select(dt => dt.IDDocumentoLote)
.ToList();
List<int?> postedDocs = lote.Documentos
.Select(pt => pt.IDDocumentoLote)
.ToList();
List<int?> deletedDocs = dbDocs
.Except(postedDocs).ToList();
//Perform deletes
foreach (var delDocId in deletedDocs)
{
if (delDocId.HasValue)
{
DocumentoLote delDoc = db.DocumentosLote
.Where(dt => dt.IDLote == lote.IDLote && dt.IDDocumentoLote == delDocId)
.Single();
db.Entry(delDoc).State = EntityState.Deleted;
}
}
//Perform insert and updates
foreach (var doc in lote.Documentos)
{
if (doc.IDDocumentoLote.HasValue)
{
db.Entry(doc).State = EntityState.Modified;
}
else
{
db.Entry(doc).State = EntityState.Added;
doc.IDLote = (int)lote.IDLote;
}
}
}
else
{
db.Lotes.Add(lote);
}
db.SaveChanges();
// If Sucess== 1 then Save/Update Successfull else there it has Exception
return Json(new { Success = 1, ex = "" });
}
else
{
return Json(new { Success = 0, ex = "Falha ao tentar salvar os dados" });
}
}
catch (Exception ex)
{
// If Sucess== 0 then Unable to perform Save/Update Operation and send Exception to View as JSON
return Json(new { Success = 0, ex = ex.Message.ToString() });
}
}
问题:嗯,我真的经历了很多,现在,我只遇到了两个问题。首先是创建抛出了一个验证异常,说它需要一个 IDLote(对于子类 - 但无论如何,如果所有者类本身在创建时仍然没有 Id,我将如何拥有它?)第二个问题:删除根本不起作用!不管我如何编码,它都会引发异常“无法定义对象,因为它们附加到不同的 ObjectContext 对象”。我真的觉得这与所有者子类之间的双向引用有关,但是仍然不知道到底发生了什么以及如何解决它
我开始觉得这里真的很失落。对此的任何想法将不胜感激。谢谢