EF:在DbContext上禁用“AutoDetectChangesEnabled”和“ProxyCreateEnabl

本文关键字:AutoDetectChangesEnabled ProxyCreateEnabl DbContext EF | 更新日期: 2023-09-27 18:09:05

  1. 知道Foo.IdBar.Id如何在不从DB加载实体的情况下创建它们的关系。

    class Foo {
        public int Id { get; set; }
        public Lst<Bar> Bars { get; set; }
    }
    class Bar {
        public int Id { get; set; }
        public Lst<Foo> Foos { get; set; }
    }
    

    此外,此配置在DbContext构造函数中被禁用:

    Configuration.AutoDetectChangesEnabled = false;
    Configuration.ProxyCreationEnabled = false;
    Configuration.LazyLoadingEnabled = false;
    
  2. 如何才能消除这种关系?


示例:

using (var ctx = new DbCtx())
{
    ctx.Configuration.LazyLoadingEnabled = false;
    ctx.Configuration.ProxyCreationEnabled = false;
    ctx.Configuration.AutoDetectChangesEnabled = false;
    ctx.Database.Log += Console.WriteLine;
    var foo = new Foo {Id = 1, Bars = new List<Bar>() };
    var bar = new Bar { Id = 3, Foos = new List<Foo>() };
    // This approach wont work, as AutoDetectChanges are disabled
    ctx.Foos.Attach(foo);
    ctx.Bars.Attach(bar);
    foo.Bars.Add(bar);
    ctx.SaveChanges();
}

在不更改配置的情况下,如何在此处定义关系。

提前谢谢。

EF:在DbContext上禁用“AutoDetectChangesEnabled”和“ProxyCreateEnabl

好的,已经找到了解决方案,这里是辅助方法:

static void ChangeRelationship<T1, T2>(
    IObjectContextAdapter ctx, 
    T1 a, 
    T2 b, 
    Expression<Func<T1, object>> getNavigationProperty,
    EntityState state) where T1: class
{
    ctx
        .ObjectContext
        .ObjectStateManager
        .ChangeRelationshipState(
            a,
            b,
            getNavigationProperty,
            state
        );
}

在我的例子中使用这个问题:

using (var ctx = new DbCtx())
{
    ctx.Configuration.LazyLoadingEnabled = false;
    ctx.Configuration.ProxyCreationEnabled = false;
    ctx.Configuration.AutoDetectChangesEnabled = false;
    ctx.Database.Log += Console.WriteLine;
    var foo = new Foo {Id = 1, Bars = new List<Bar>()};
    var bar = new Bar { Id = 3, Foos = new List<Foo>() };
    ctx.Entry(foo).State = EntityState.Unchanged;
    ctx.Entry(bar).State = EntityState.Unchanged;
    // create
    ChangeRelationship(ctx, foo, bar, x => x.Bars, EntityState.Added);
    ctx.SaveChanges();
    // remove
    ChangeRelationship(ctx, foo, bar, x => x.Bars, EntityState.Deleted);
    ctx.SaveChanges();
}

如果我理解正确,您希望在不查找Foo实体的情况下将Bar对象添加到现有的Foo实体中。

假设您有Foo(id=1(已经存在。想要添加新的Bar(id=100(实体。

using (var context = new Context())
{
    var bar = new Bar() { Id = 100 };
    var foo = new Foo() { Id = 1 }; // Only ID is required
    context.Foos.Attach(foo);
    bar.Foos.Add(foo);
    context.Bars.Add(bar);
    context.SaveChanges();
}

您提出的问题是可能的。以下是步骤:

(1( 首先创建两个只指定PK的实体实例,并将其中一个(例如foo(附加到上下文:

var foo = new Foo { Id = fooId };
var bar = new Bar { Id = barId };
ctx.Foos.Attach(foo);

(2( 将第二个实体集合设置为包含第一个实体的新列表(即"创建"关系(:

bar.Foos = new List<Foo> { foo };

(3( 将第二个实体标记如下:

(A(添加关系:

ctx.Entry(bar).State = EntityState.Added;

(B(删除关系:

ctx.Entry(bar).State = EntityState.Deleted;

(4( 将第二个实体标记为未更改:

ctx.Entry(bar).State = EntityState.Unchanged;

就这样!

调用ctx.SaveChanges();后,将在连接表中添加或删除关系。

更新:虽然上述方法有效(实际上,如果我们在最后显式调用DbContext.ChangeTracker.DetectChanges(),我的原始解决方案即用"原始"集合附加第二个实体,然后模拟修改也有效(,但我应该承认,您发现的ObjectContext解决方案看起来更自然(奇怪的是,这样的功能没有通过DbContext公开(,所以我个人的投票就在那里。

相关文章:
  • 没有找到相关文章