简体   繁体   中英

EF6 write once to DB with FK relation

I am wondering if it is possible to write once to the database on two objects where one object has a FK to the other. For example lets say the DB structure is:

C1

public class Team {
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id {get; set;}
}

public class Player {
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id {get; set;}
    public Guid TeamId {get; set;}
    public virtual Team Team {get; set;}
}

Now I have a class that will create players and teams. At the moment I am doing it like this:

C2

public async Task<bool> CreateTeams(){
    var teams = new List<Teams>();

    while (i < 5){
        var team = new Team();
        teams.Add(team);
        //Assume Db is being instantiated somewhere else in the code
        Db.Teams.Add(team);
    }

    if(await Db.SaveChangesAsync() > 0){
        foreach(var team in teams){
            var player = new Player{
                player.TeamId = team.Id;
            }
            Db.Players.Add(player);
        }
        await Db.SaveChangesAsync();
    }
}

As you can see, I am making two DB calls to be able to create 5 teams with 1 player in each team. I am wondering if there is a more efficient way of accomplishing. Is it possible to do this with a single Database call, something like this possibly?

C3

public async Task<bool> CreateTeams(){
    while (i < 5){
        var team = new Team();
        //Assume Db is being instantiated somewhere else in the code
        Db.Teams.Add(team);
        Db.Players.Add(new Player {TeamId = team.Id});
    }

    await Db.SaveChangesAsync();
}

Of course the above code doesn't work, hence why I am asking if it is possible somehow. I am theorizing that if I assign the whole Team object it could possibly work? For example:

C4

public async Task<bool> CreateTeams(){
    while (i < 5){
        var team = new Team();
        //Assume Db is being instantiated somewhere else in the code
        Db.Teams.Add(team);
        Db.Players.Add(new Player {Team = team});
    }

    await Db.SaveChangesAsync();
}

Is what I am trying to do possible in any way?

One of the primary benefits of EF (or any ORM) is that is does exactly that for you. You can create arbitrarily large graphs of objects in memory and save them all to multiple tables with a single SaveChanges() call.

What you can't expect EF to do is to create a single SQL statement that will do all that, but while it will perform multiple SQL statements, only one SaveChanges() is needed.

This does depend on you setting up your persistence model correctly. I can't see anything particularly wrong with yours (you could add a virtual collection of Player in Team, although I don't think that's required).

You example C4 should just work - does it not?

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