Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
500 views
in Technique[技术] by (71.8m points)

c# - EF: Create/Remove relation from Many-to-Many relations when `AutoDetectChangesEnabled` and `ProxyCreationEnabled` are disabled on DbContext

  1. Knowning Foo.Id and Bar.Id how can I create their relation without loading the entities from the 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; }
    }
    

    Also this configuration are disabled in DbContext constructor:

    Configuration.AutoDetectChangesEnabled = false;
    Configuration.ProxyCreationEnabled = false;
    Configuration.LazyLoadingEnabled = false;
    
  2. And how it is possible to remove the relationship?


Example:

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();
}

How can I define relation here, without changing the configuration.

Thank you in advance.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Ok, have found the solution and here is the helper method:

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
        );
}

And using it in my example from the question:

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();
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...