0

I am making a logging program that logs stats from a game. i have a db with unique Players. Upon a new game i load the players and associate them with a dataset of the type PlayerData which i save to the db at the end of the round.

My problem is, that when i save MatchData which contains references to the already exixting players in db, i save the same players again to the db and therefore duplicate them. (which i bad!)

Can't entity framework just save a reference to the player already in the database? Ane if, how? if not, do you guys have a walkaround to this issue?

MatchData class holds data for a specific match:

public class MatchData
{
    [Key]
    public int Id { get; set; }
    private List<PlayerData> blueTeam = new List<PlayerData>();
    private List<PlayerData> redTeam = new List<PlayerData>();
    //other relevant data
}

PlayerData class holds data for a specific player in a match:

public class PlayerData
{
    [Key]
    public int Id { get; set; }
    public Player Player { get; set; }
    //other relevant data
}

Player class holds the data for a specific player for life (stats, name, email, etc):

public class Player
{
    [Key]
    private int id;       // full props
    private string name;  // full props
    private string email; // full props
    //other relevant data
}

DBContext:

class DBBooneContext : DbContext
{
    public DbSet<Player> Player { get; set; }
    public DbSet<PlayerData> PlayerData { get; set; }
    public DbSet<MatchData> MatchData { get; set; }
}

And here is how i save the matchData to db.

public static void SaveMatchData(MatchData matchData)
{
    using (DBBooneContext db = new DBBooneContext())
    {
        db.MatchData.Add(matchData);
        db.SaveChanges();
    }
}
abatishchev
  • 98,240
  • 88
  • 296
  • 433
Mads Gadeberg
  • 1,429
  • 3
  • 20
  • 30
  • what version of EF? What does your DbContext look like -- specifically your DbSets and relationships? Could you post a the snippet of where you save MatchData? – Michael Finger Mar 23 '14 at 11:11
  • There is something terribly wrong with the player class as there are only private fields rather than public properties. – Wiktor Zychla Mar 23 '14 at 14:19
  • Wiktor Zychla: its just a snippit.. didnt want to post all the code. Dont think about it.. it works just fine :) Michael Finger: i just updated the question for you. if you need more information plz let me know. – Mads Gadeberg Mar 23 '14 at 15:05
  • If you're in the development stage why don't upgrade to the EF latest? Just curious. – abatishchev Mar 23 '14 at 19:58
  • Apparently, `PlayerData.Player` is loaded when yo save the data. Try to prevent that. By `db.MatchData.Add(matchData)` everything contained by `matchData` is marked as `Added`. – Gert Arnold Mar 23 '14 at 21:48
  • So here we are: When i execute 'db.MatchData.Add(matchData);' i add the matchData object and therefore i also add the same players becouse MatchData contain players. Cant entity framework Do all the work for me? I mean update players if the [key] exist in db, instead of duplicating them with a new [Key]. - Any sugestions on how to fix this? i have absolutley no clue. @abatishchev good point you got there. i will read some litterature on the switch. – Mads Gadeberg Mar 24 '14 at 08:10

1 Answers1

0

You need to walk through the graph of both your ICollection (RedTeam, BlueTeam) in MatchData and determine which PlayerData objects are new (Add), already exist (Attach), or need to be deleted (Remove).

See the approved answer here: The relationship could not be changed because one or more of the foreign-key properties is non-nullable

Note: you can also delete all the children and re-add them (as other answers in same link demonstrate). The code is much simpler, but your sql overhead may be much higher.

Community
  • 1
  • 1
Michael Finger
  • 1,110
  • 9
  • 9
  • All of My players is in the database. When the program starts it loads all the players from the db. I just want to save a new object thet contains a reference to those players. – Mads Gadeberg Mar 24 '14 at 15:18