Working with linked objects in EF C #

I have objects A

and B

.

A

has fields: id

(PK) and b_fk

(from FK to B id

). B

has similar fields: id

(PK) and a_fk

(FK before A id

).

Now I want to create an object A

and B

:

createAAndBMethod(Entities context){
    A a = new A();
    B b = new B();
    a.b_fk = b;
    b.a_fk = a;
    context.As.AddObject(a);
    context.Bs.AddObject(b);
}

someImportantMethod(){
    //do sth
    Entities context = new Entities(...);
    //do sth, maybe some changes to db on context
    createAAndBMethod(context);
    //do sth, maybe some changes to db on context
    context.SaveChanges();// <-- here I'm getting error
}

      

Saving fails with error: Unable to determine a valid ordering for dependent operations. Dependencies may exist due to foreign key constraints, model requirements, or store-generated values.

Is there a way to make this work with a single save? I need to create both objects in some code that shouldn't save the changes, so I can't execute context.SaveChanges()

anywhere before.

In context.SaveChanges()

something can happen like this:

 Create newA with nulled field b_fk
 Create newB with a_fk = newA
 Set newA.b_fk to newB

      

Update: both a_fk

and b_fk

are null. I am working with MS SQL and Azure SQL.

Update2: I changed createAAndBMethod(Entities context)

to:

createAAndBMethod(Entities context){
    A a = new A();
    context.As.AddObject(a);
    B b = new B();
    a.b_fk = b;
}

      

But it still doesn't work with the same error.

+3


source to share


3 answers


I think you have a problem with the model; The table has a foreign key reference to table B; and table B has a foreign key reference to the table. Then why don't you combine these tables and create just one table?

If you are trying to create a one-to-one relationship, you are not.



UPDATE: DB design is wrong. It is sufficient to create only a foreign key in table B. there is no need to create a foreign key in table A, since such a construction satisfies "A can have 0 or many Bs".

+1


source


Try to remove these lines:

b.a_fk = a;

context.Bs.AddObject(b);

      

I think you are adding the object b

to the context twice. EF do this automatically when you add a a

foreign key object .



Update:

try these 2 options:

  createAAndBMethod1(Entities context)
  {
        A a = new A();
        B b = new B();
        a.b_fk = b;
        b.a_fk = a;
        context.As.AddObject(a);
  } 

createAAndBMethod2(Entities context)
{
        A a = new A();
        B b = new B();
        a.b_fk = b;
        context.As.AddObject(a);
        context.SaveChanges();
        b.a_fk = a;
        context.SaveChanges();    
}

      

+1


source


Something like that you want to use one context and at the same time you have two tables.

    var p = new Person()
    {
        LastName = "test1111111111",
    };
    var c = new Child()
    {
        Name = "Testchild"
    };
    PersonTest(p, c);

      


    public void PersonTest(Person ob, Child ob2)
    {
        try
        {
            using (var con = new Entities())
            {
                con.Configuration.AutoDetectChangesEnabled = false;
                var o = new Person();
                if (ob.PersonId > 0)
                    o = con.People.Find(ob.PersonId);

                o.PersonId = ob.PersonId;
                o.LastName = ob.LastName;
                if (ob.PersonId == 0)
                    con.People.Add(o);
                con.ChangeTracker.DetectChanges();
                con.SaveChanges();
                i = o.PersonId;

                var o2 = new Child();
                if (ob2.ChildrenId > 0)
                    o2 = con.Children.Find(ob.PersonId);

                o2.PersonId = ob2.ChildrenId;
                o2.Name = ob2.Name;
                o2.PersonId = i;
                if (ob2.ChildrenId == 0)
                    con.Children.Add(o2);
                con.SaveChanges();
            }
        }
        catch (Exception ex)
        {
            throw new Exception(ex.InnerException.Message);
        }
        finally
        {
            con.Configuration.AutoDetectChangesEnabled = true;
        }
    }

      

0


source







All Articles