2

as I wrote in title, I have this code:

public class ApplicationUser : IdentityUser
{
    public virtual MapPosition MapPosition { get; set; }

    public ApplicationUser()
    {
        MapPosition = new MapPosition { PositionX = 0, PositionY = 0 };
    }

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        return userIdentity;
    }
}

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public DbSet<MapPosition> MapPositions { get; set; }

    public ApplicationDbContext()
        : base("DefaultConnection", throwIfV1Schema: false)
    {
    }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }
}

And in my controller I have method that I call from @Ajax.ActionLink in my view:

public string ChangeXPosition()
    {
        var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
        // Get the current logged in User and look up the user in ASP.NET Identity
        currentUser = manager.FindById(User.Identity.GetUserId());
        currentUser.MapPosition.PositionX++;

        //manager.Update(currentUser);
        Debug.WriteLine("currentUser.MapPosition.PositionX: " + currentUser.MapPosition.PositionX);

        return "currentUser.MapPosition.PositionX: " + currentUser.MapPosition.PositionX;
    }

I want to save to database changed value of currentUser.MapPosition.PositionX. I have found numerous ways to solve this problem, but none of them worked with my project.

I tried those solutions:

how-to-update-identityuser-with-custom-properties-using-mvc5-and-entity-framewor

updating-user-data-asp-net-identity

mvc5-applicationuser-custom-properties

UPDATE Ok so I tried to do as you said, but still doesn't work:

public class ApplicationUser : IdentityUser
{
    public virtual MapPosition MapPosition { get; set; }

    public ApplicationUser()
    {
    }
}

This version works, my controller method does change the value in the table. But it works only for user, that have been already created. When I create a new User, his new MapPositions record is not created.

public class ApplicationUser : IdentityUser
{
    private MapPosition _mapPosition;
    public virtual MapPosition MapPosition
    {
        get { return _mapPosition ?? (_mapPosition = new MapPosition()); }
    }

    public ApplicationUser()
    {
    }
}

This version doesn't work at all, doesn't change the value in database and doesn't create record in MapPositions when new user is created.

1
  • Please describe what are the approaches, which you have tried and which not worked for your case. Commented Jun 25, 2015 at 22:54

1 Answer 1

4

At least you have to invoke SaveChanges method on the current ApplicationDbContext instance after updating the entity instance's fields/properties (currentUser.MapPosition.PositionX in your case):

public string ChangeXPosition()
    {
        var dbContext = new ApplicationDbContext();
        var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(dbContext));
        // Get the current logged in User and look up the user in ASP.NET Identity
        currentUser = manager.FindById(User.Identity.GetUserId());
        currentUser.MapPosition.PositionX++;

        //manager.Update(currentUser);
        Debug.WriteLine("currentUser.MapPosition.PositionX: " + currentUser.MapPosition.PositionX);
        dbContext.SaveChanges();
        return "currentUser.MapPosition.PositionX: " + currentUser.MapPosition.PositionX;
    }

If it does not help, then you have to explicitly mark the corresponding entry as Modified in the DbContext's change tracker in the following way:

dbContext.Entry(currentUser.MapPosition).State = EntityState.Modified;

After that the change should occur in a database as you can see by manually checking the data in the corresponding table at the database (by using Visual Studio SQL Server Data Tools extension, SQL Server Management Studio or any other database management tool).

Sign up to request clarification or add additional context in comments.

3 Comments

With the addition of this dbContext.Entry it works, value changes in database. But no idea why, each time I invoke this method, it starts again with 0 (and changing it to one)...
@user3662546, I suppose it's because you are explicitly instantiating MapPosition in the constructor of ApplicationUser class, so it is not pulled from the database even if lazy loading enabled. Check the part about reference properties of this answer on SO. So I suggest you to remove that initialization from the constructor's code.
I tried to do as you instructed, but still doesn't work. Maybe (probably) I did something wrong.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.