防止EF保存完整的对象图

3

I have a model as below

public class Lesson
{

    public int Id { get; set; }
    public Section Div { get; set; }

}

public class Section
{

    public int Id { get; set; }

    public string Name { get; set; }
}

我也有以下的DB上下文:
public class MyContext : DbContext
{

    public MyContext() : base("DefaultConnection")
    {
        this.Configuration.LazyLoadingEnabled = false;
        this.Configuration.ProxyCreationEnabled = false;
    }

    public DbSet<Lesson> Lessons { get; set; }
    public DbSet<Section> Sections { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
    }

}

然后我使用以下代码调用数据库

            using (MyContext c = new EFTest.MyContext())
            {

                Lesson d = new EFTest.Lesson();
                Section ed = new EFTest.Section() { Name = "a" };
                d.Div = ed;

                c.Entry(d.Div).State = EntityState.Detached;

                c.Lessons.Add(d);
                c.SaveChanges();
            }

我希望这段代码只保存Lesson对象,而不是保存Lesson和Section的完整图形,但实际上它保存了整个图形。如何防止它这样做?


使用.AsNoTracking(),关系修复不应该发生,您的DbSets也不应该有其他引用。根据检索和保存数据之间的操作,您可能还需要禁用ChangeTracking。 - DevilSuichiro
我没有检索数据,正如您在示例中所看到的,我是从头开始创建对象,然后将它们发送到数据库。 - Sisyphus
当两个对象都处于上下文(添加状态)中,它将执行此操作,并且它们之间映射的导航属性已填充并调用了.SaveChanges。如果您想按顺序添加对象,则必须自己获取ID值并设置FK(id属性将在.SaveChanges()调用后设置)。 - DevilSuichiro
我想手动为每个对象调用Add方法,因此如果对象图有5个对象,则我会针对每个对象调用5个Add方法,并且每个Add方法位于相应的存储库中。 - Sisyphus
@DevilSuichiro,您能否用伪代码简要解释一下? - Sisyphus
显示剩余3条评论
1个回答

0

当你将一个实体添加到DbSet中时,实体框架会自动添加其所有关联。在将父实体添加到DbSet后,您需要分离不想添加的实体。

using (MyContext c = new EFTest.MyContext())
{

    Lesson d = new EFTest.Lesson();
    Section ed = new EFTest.Section() { Name = "a" };
    d.Div = ed;

    c.Lessons.Add(d);

    c.Entry(d.Div).State = EntityState.Detached;

    c.SaveChanges();
}

如果您想添加与课程相关的部分,您需要使用相同的上下文或创建新的上下文并加载该课程。
您可以使用以下代码。
using (MyContext c = new EFTest.MyContext())
{

    Lesson d = new EFTest.Lesson();
    Section ed = new EFTest.Section() { Name = "a" };
    d.Div = ed;

    c.Lessons.Add(d);

    c.Entry(d.Div).State = EntityState.Detached;

    c.SaveChanges();

    //you can use this code
        ed.Lesson = d;
    // or this code
        d.Div = ed;

    c.Sections.Add(ed);
    c.SaveChanges();
}

谢谢你的回答,现在我遇到了另一个问题,能否请你查看一下初始帖子中的评论,也许你可以帮助我。 - Sisyphus
但是我的Section类中没有一个指向Lesson的属性。 - Sisyphus
@Sisyphus,你需要添加它,可以根据你的需求添加一个Lesson或者一个List<Lesson>。这不应该改变你的数据库,也不需要进行迁移,因为关系已经存在。 - Kahbazi
我也不确定关系修复是否适用于分离的条目。但是,反向导航属性不应该对关系修复造成影响。 - DevilSuichiro
@Arvin,我认为这会起作用,但这会在我的领域模型中添加一个不必要的额外关系,还有其他解决方案吗? - Sisyphus
@Sisyphus,你也可以再次将你的部分添加到你的课程中,我会编辑我的答案。 - Kahbazi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接