ObjectSet<T>.AddObject() vs. EntityCollection<T>.Add()
Let's say I have two EntitySets, "Teams" and "Players".
开发者_C百科I am adding new teams to the system, for sake of argument, let's say I'm adding a thousand teams from a file (which contains duplicates).
The system contains 100 teams to start. And my goal is to avoid duplicates without calling SaveChanges() for every team added.
The process is to query that the newteam doesn't already exist, Then add the new team if not exist.
var team = (from t in context.Teams
where t.Name == newTeam.Name
select t).FirstOrDefault();
if (team==null)
--Add New Team
If I add using context.Teams.AddObject(newTeam);
or context.AddObject("Teams",newTeam);
The team.Count() will remain 100 and if you ran the query again, var team would be null.
However, If I instead use player.Teams.Add(newTeam);
to add the team, everything works perfectly, except I have to have a player to add the NewTeam to and that player will be a member of all new teams.
After calling player.Teams.Add(newTeam);
The query will return the new team.
var team = (from t in player.teams
where t.Name = newTeam.Name
select t).FirstOrDefault();
player.Teams.Count()
will increase by one.
In the first example context.Teams is an ObjectSet<T>,
whereas, in player.Teams.Add Teams is an EntityCollection<T>
. I would think these would behave the same, but they do not.
Is there a way to make the ObjectSet<T>
behave like the EntityCollection<T>
? I want to call SaveChanges once and only once after all teams have been added from the file.
Or is there a better way that I am not seeing?
Thanks!
No there is no way to make them behave the same. ObjectSet
represents database query and once you use it you are always doing query to the database where your new team is not present yet. EntityCollection
is local collection of loaded entities and if you use it you are doing query to your application memory.
Generally using EntityCollection
is exactly same as maintaining separate List<Team>
:
List<Team> teams = context.Teams.ToList();
var team = teams.FirstOrDefault(t => t.Name == newTeam.Name);
if (team == null)
{
context.Teams.AddObject(newTeam);
teams.Add(newTeam);
}
context.SaveChanges();
You can also use Dictionary<string, Team>
and get probably better performance instead of searching the list for each team.
"If I add using context.Teams.AddObject(newTeam); or context.AddObject("Teams",newTeam);
The team.Count() will remain 100 and if you ran the query again, var team would be null."
The teams won't be added until you call the SaveChanges() method.
I'm guessing that by adding to the Player table Navigation property it is actually writing to the Team table before the SaveChanges() method is called.
I would consider putting all the new Teams in a List and then running a distinct on that list. Maybe something like this...
//an array of the new teams
var newTeams = {"Chi","Cle","La","Ny"};
//a list of the teams in the database
var teamsInDb = context.Teams.ToList();
//a query to get the unique teams that are not in the database
var uniqueTeams = newTeams.Where(t => !teamsInDb.Contains(t)).Distinct();
//iterate the new teams and add them
foreach(var t in uniqueTeams)
{
context.Teams.AddObject(t);
}
//save
context.SaveChanges();
精彩评论