1

I'm trying to save an object to my database, but I cannot because of the above specified exception message.

Here's what I'm doing:

Player player = playerRepository.Find(universeId, playerId);
UserProperties userProperties = userPropertiesRepository.Find(User.Identity.GetUserId());

rated = new Ratings
{
    Player = player,
    RatingType = ratingsIdentifier,
    UserProperties = userProperties
};

ratingsRepository.InsertOrUpdate(rated);

The InsertOrUpdate() (and Save()) method:

public void InsertOrUpdate(Ratings ratings)
{
    if (ratings.RatingsId == default(int))
    {
        // New entity
        context.Ratings.Add(ratings); // this is where the exception happens
    }
    else
    {
        // Existing entity
        context.Entry(ratings).State = EntityState.Modified;
    }

    Save();
}

public void Save()
{
    context.SaveChanges();
}

I have a basic understanding of the issue, I just don't know how to resolve it. I can tell that it has to do with the Player and UserProperties objects, because if they're null, it doesn't crap itself when I try to save.

My context class:

public class ApplicationUser : IdentityUser
{
}

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("DefaultConnection")
    {
    }

    public DbSet<Player> Players { get; set; }
    public DbSet<ServerData> ServerDatas { get; set; }
    public DbSet<Ratings> Ratings { get; set; }
    public DbSet<UserProperties> UserProperties { get; set; }

    // some more DbSet<>
}

I have tried reading the other topics about this, but I can't, for example, detach() on IdentityDbContext. I'm totally at a loss here.

MrGraversen
  • 257
  • 2
  • 15
  • Is your `userPropertiesRepository` using the same instance of the context as the `playerRepository`? – DavidG May 16 '14 at 20:38
  • Each repository has the line `private readonly ApplicationDbContext context = new ApplicationDbContext();` at the top. It's just what was scaffolded by MvcScaffold. – MrGraversen May 16 '14 at 23:20
  • You need to have a single context to be able to use both repositories at the same time. – DavidG May 17 '14 at 01:36
  • How do I correctly implement this? A singleton context seems to be a bad idea. Got any advice for me? – MrGraversen May 17 '14 at 13:35
  • Yes, a singleton is a bad idea, there's a good [explanation here](http://stackoverflow.com/questions/3653009/entity-framework-and-connection-pooling/3653392#3653392). Instead, I'd pass the context into your repositories in the constructor. – DavidG May 17 '14 at 15:42
  • I understand the root issue, but I don't know how to solve it correctly. You're saying you would pass the context into the repositories in the constructor, but when and where is *that* context instanced? – MrGraversen May 18 '14 at 11:55
  • 1
    See my answer, I hope that solves your issue. – DavidG May 18 '14 at 21:17

1 Answers1

1

You need to ensure that all repositories are using the same context for atomic operations. so you need to create your context and pass that into your repositories in the constructor. Something like this:

var ctx = new ApplicationDbContext();
var playerRepository = new PlayerRepository(ctx);
var userPropertiesRepository = new UserPropertiesRepository(ctx);
DavidG
  • 95,392
  • 10
  • 185
  • 181
  • Thanks, I used http://stackoverflow.com/questions/21671590/how-to-handle-this-scenario-in-mvc-c to solve my problem. – MrGraversen May 19 '14 at 10:33
  • Yes, the UoW paradigm is usually used in conjunction with repositories. Glad you got it sorted. – DavidG May 19 '14 at 12:23