如何保存带有导航属性的项目到DB实体框架

本文关键字:项目 属性 DB 框架 实体 导航 何保存 保存 | 更新日期: 2023-09-27 18:02:54

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不是,我预计,当我保存到DB Site A Site.Pages也将保存到DB,并且对于每个Page navigation property Site将被设置为A。页面正在保存,但数据库中的Site_Id为空。我应该创建自己的外键还是有可能使用实体框架键?

如何保存带有导航属性的项目到DB实体框架

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

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)为每个nav属性添加public int FieldId
2)删除并重建数据库
3)int在默认情况下是不可空的,所以当尝试添加新记录时EF会抛出异常

换句话说,我让EF抛出异常,如果它不能设置导航属性,它可以帮助我找到我的代码中的错误(只是设置断点之前崩溃和调试一步一步)。默认情况下,如果无法设置导航属性EF,则将其设置为NULL