如何将具有导航属性的项目保存到DB Entity Framework 6

时间:2016-08-17 20:15:44

标签: c# entity-framework

public void Add(Site obj)
{
    if(obj.Id == 0 || obj.Id >= 10000)
    {
        context.Sites.Add(obj);
    } else
    {
        Site dbEntry = context.Sites.Find(obj.Id);
        if (dbEntry != null)
        {
             ...
        }
    }
    context.SaveChanges();
    return res;
}

class Site {
  public virtual List<Page> Pages { get; set; }
}

class Page {
    public virtual Site Site {get;set;}
}

在添加方法Obj.Pages.Site(foreach of pages)为空,但Site.Pages没有,我预计当我保存到数据库Site A Site.Pages时也会保存到数据库中,并且每个Page navigation property Site将设置为A。页面正在保存,但db中的Site_Id为空。我应该创建自己的外键还是可以使用实体框架键?

2 个答案:

答案 0 :(得分:1)

添加网站后,将SaveChanges()移至if语句。基本上, 您必须先保存更改并提交事务,然后才能访问所有导航属性。使用context.Database.BeginTransaction()提交事务是可选的,因此您可以在出现问题时回滚。但是在尝试访问导航属性之前必须先进行savechange。尝试将代码分离为函数,以便更容易阅读。一个例子是这样的:

public void Add(Site obj)
{
    using(var context = new SiteContext())
    {
        using(var dbContextTransaction = new context.Database.BeginTransaction())
        {
            try
            {
                context.Sites.Add(obj);
                context.Entry(obj).State = obj.Id == 0 ? EntityState.Added : EntityState.Modified;
                context.SaveChanges();
                dbContextTransaction.Commit();
            }
            catch (Exception ex)
            {
                dbContextTransaction.Rollback();
                throw;
            }
        }
    }
}

然后,如果你想获得相同的条目,你应该做类似的事情

public Site GetSiteById(int id)
{
    using(var context = new SiteContext())
    {
        return context.Sites.FirstOrDefault(i => i.Id == id);
    }
}

但是,上下文必须先保存更改并提交事务。然后,您将填满所有属性。

答案 1 :(得分:0)

此代码有效。要找出问题,我已经完成了下一步:

1)为每个nav属性添加public int FieldId
2)删除并重新创建数据库
3)默认情况下int不可为空,所以现在当尝试添加新记录时EF抛出异常

换句话说,如果不能设置导航属性,我会使EF抛出异常,这有助于我在代码中找到错误(只需在崩溃前设置断点并逐步调试)。默认情况下,如果无法设置导航属性,则将其设置为NULL