简体   繁体   中英

Add new and update existed object into many-to-many table with EF

class A
{
    int Id; //Primary key
    string Name;
}

class B
{
    int Id; //Primary key
    string Name;
}

class AB
{
    int Id; //PK
    int AId; //FK
    int BId; //FK
}

In this situation: "A" exists in database "B" and "AB" are new created objects.

A a = new A("asd");
B b = new B("qwe");
AB ab = new AB(1, 1);

How should I add this with Entity Framework to database?

Is it something like this? It should be 3 context for each entity?

mydb.A.Context.ApplyCurrentValues(a)
mydb.B.Context.AddObject(b)
mydb.AB.Context.AddObject(ab) //connected with A and B above

In a database first approach, firstly you entity AB unnecessarily has a primary key as its an associative entity only. Unless you want to hold other attributes on that table a Pk is not necessary and would result in EF 4 creating a separate entity.

Db Diagram of relationship:

在此输入图像描述

EF edmx result:

在此输入图像描述

Using that relationship to answer your question.

    public void addNewBtoA(B newEntity, A existingEntity) {

        _myContext.Attach(existingEntity);
        existingEntity.B.Add(newEntity);
        myContext.SaveChanges();

    }

EDIT:

An AB record is automatically created by EF in the Db for the many to many relationship.

EDIT 2:

If entity AB has other properties on it then EF will import it as a separate entity, updating the context would go summing like this:

B b = new B {
    Name = "name"
};

AB ab = new AB {

    A = existingA,
    B = b,
    arbitraryProp = "my heart is a fist of blood" 

}

_myContext.Attach(existingA);
_myContext.Add(b);
_myContext.Add(ab);
_myContext.SaveChanges();

The order of the add is irrelevant as EF determines the order of insertion based on the model relationships defined in the .edmx. Remember that attaching existingA is only necessary if existingA is not currently tracked by the _myContext - ie if existingA was fetched using _myContext.A.SingleOrDefault() then it is already attached.

EDIT 3:

public void testab() {
            A existingA = new A {
                Name = "test a"
            };

            using (ABEntities context = new ABEntities()) {
                context.A.AddObject(existingA);

                context.SaveChanges();
            }


            using (ABEntities context = new ABEntities()) {
                B newB = new B {
                    Name = "test b"
                };

                context.Attach(existingA);
                existingA.B.Add(newB);
                context.SaveChanges();
            }
        }

You need modify your AB class definition as follows

class AB
{
    public int Id { get; set; }
    public virtual A A { get; set; }
    public virtual B B { get; set; }
}

Then

AB ab = new AB { A = a, B = b };

// if 'a' is not attached call mydb.A.Attach(a);
mydb.AB.AddObject(ab);

EF will figure out the insertion order of the entities.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM