Reputation: 99
I have a Web API application with entity framework 6. I have 2 entities - Player and Match with many to many relationship between them:
public class Player {
public string PlayerId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public virtual ICollection<Match> Matches { get; set; }
}
public class Match {
public string MatchId { get; set; }
public DateTime DateTime { get; set; }
public virtual ICollection<Player> Players { get; set; }
}
This is how my DBContext looks like:
public class FIFA15RankingContext : DbContext {
public DbSet<Player> Players { get; set; }
public DbSet<Match> Matches { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Entity<Player>()
.HasMany(t => t.Matches)
.WithMany(t => t.Players)
.Map(m => {
m.ToTable("PlayerMatches");
m.MapLeftKey("PlayerId");
m.MapRightKey("MatchId");
}
);
base.OnModelCreating(modelBuilder);
}
}
EF created for me behind the scenes the table PlayerMatches (PlayerId, MatchId).
This is my MatchesController (as scaffolded by VS 2013):
// POST: api/Matches
[ResponseType(typeof(Match))]
public async Task<IHttpActionResult> PostMatch(Match match)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
db.Matches.Add(match);
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateException)
{
if (MatchExists(match.MatchId))
return Conflict();
else
throw;
}
return CreatedAtRoute("DefaultApi", new { id = match.MatchId }, match);
}
I want to be able to create new match and associate with it existing users. I couldn't make it work in any other way but to add this code (which smells pretty bad) before db.Matches.Add(match):
var playersFromDB = new List<Player>();
if (match.Players != null) {
foreach (var p in match.Players) {
playersFromDB.Add(db.Players.Find(p.PlayerId));
}
}
match.Players = playersFromDB;
What am I doing wrong?
Upvotes: 1
Views: 237
Reputation: 16573
Manually attach the User
entities and set their state to Unchanged
foreach( var p in match.Players )
{
db.Entry( p ).State = EntityState.Unchanged;
}
Upvotes: 0
Reputation: 11964
If all players already exists in database, you can attach them to dbcontext instead of load from db.
if (match.Players != null) {
foreach (var player in match.Players) {
db.Players.Attach(player);
}
}
Upvotes: 1