首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >EntityFramework和ont-to-many操作

EntityFramework和ont-to-many操作
EN

Stack Overflow用户
提问于 2012-11-12 21:13:35
回答 1查看 699关注 0票数 0

我真的很努力地把我的项目中的所有东西都与EF一起工作,但这真的变得越来越困难,有时它让我怀疑这是否真的是明智之举(依赖EF而不是编码数据库的所有细节)。好吧,我的问题仍然与1-N创建/编辑/删除功能有关(应该很简单,对吧?)。

好的,我在这里粘贴了一些与我的代码相同的简单代码。

对于实体,我获得的主类如下:

代码语言:javascript
复制
[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 -否则它会抛出验证异常,要求在创建时提供一个值

对于child类,我得到了以下内容:

代码语言:javascript
复制
[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; }
}

注意,子类有一个对owner类的引用,这是"IDLote“和"Lote”属性,owner类有一个子类实例列表-所以我得到了双向引用-我假设这与问题有某种关系

我得到了一个由VS2012自动生成的控制器和视图,它具有与Lote类相关的读/写功能。我在视图中所做的事情可以描述为:我使用Jquery DataTable来管理子类数据(用户可以在DataTable上添加"N“个实例)。我将Post Button替换为对JS方法的调用,该方法只是从表单和DataTable获取所有数据,并将其包装在JSon对象中,然后通过Ajax将其发送给控制器。

接收它的控制器方法可以简化为:

代码语言:javascript
复制
    [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对象”。我真的觉得这与所有者-孩子类之间的双向引用有关,但仍然不知道到底发生了什么以及如何解决它

我开始觉得在这里真的迷失了。任何关于这方面的想法都将非常感谢。谢谢

EN

回答 1

Stack Overflow用户

发布于 2013-10-29 08:50:22

由于对这个老问题有很多观点,现在我确实有了一些答案,我将它们张贴出来以供参考:

Q-关于键属性的int?类型:A-它根本不需要是一个可以为空的整型。实体可以用一个简单的整型属性作为键来声明,当从视图发送JSon对象返回到某个控制器方法时,这个属性(键)可以用值"0“填充。EF将在持久化对象后立即生成正确的值。

Q-关于导航属性,以及当两个类都没有在关键字上获得值(非零)时如何实现两个类之间的关系:A-要发回的JSon对象可以实现它们之间的精确导航关系。当控制器将发布的数据绑定到它应该接收的模型时,它将“理解”它们的关系,并且一旦生成了键的值,它们将正确地相互引用。

Q-关于delete方法尝试中描述的错误:A-当对象应该与其他对象交互时,这些交互应该被EF以任何方式持久化或“理解”,它们必须已经获得,生成或附加到相同的DBContext。EF依赖于DB上下文来创建此交互的树,因此,当objets不存在于相同的DB上下文中时,不可能构建此树。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13344371

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档