Vague
Vague

Reputation: 2280

Entity Framework 6 dbContext not saving changes

In our MVC 5 project our database context is instantiate in the AccountController like this

    private CustomersContext _customersContext;

    public CustomersContext CustContext
    {
        get
        {
            return _customersContext ?? new CustomersContext();
        }
        private set
        {
            _customersContext = value;
        }
    }

Each customer is referred by a number of sources. The routine below changes the UserId of the referral source to a new user.

        var referralList = CustContext.Referrals.Where(d => d.UserId == membershipUser.Id);
        foreach (Referral referral in referralList)
        {
            referral.UserId = newUser.Id;
        }

Stepping trough the code I can see referral.UserId being updated. However

var result = await CustContext.SaveChangesAsync();

returns 0. The database is not updated.

CustomersContext looks like this

{
public partial class CustomersContext : IdentityDbContext<ApplicationUser>//, ICustomersContext
{

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

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

    public virtual DbSet<ReferralSource> ReferralSources { get; set; }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<ApplicationUser>()
            .HasMany(e => e.Referrals)
            .WithRequired(e => e.User)
            .HasForeignKey(e => e.UserId)
            .WillCascadeOnDelete(false);

I don't see any sql emitted in SQL Profiler. Why doesn't the database context save changes?

Upvotes: 0

Views: 1563

Answers (2)

Vague
Vague

Reputation: 2280

The answer provided by @Issac did not solve my problem, but it did put me on the road to a solution. The error

An entity object cannot be referenced by multiple instances of IEntityChangeTracker.

suggested there were multiple instances of dbContext. I removed the context from the CTOR and instantiated the context within a using statement

using (CustomersContext customersContext = new CustomersContext())
{
    var referralList = customersContext.Referrals.Where(d => d.UserId == membershipUser.Id);
    foreach (Referral referral in referralList)
    {
        referral.UserId = newUser.Id;
    }
    var result = await customersContext.SaveChangesAsync();
}

and now all is tickety-boo

Upvotes: 1

Issac
Issac

Reputation: 963

Before calling var result = await CustContext.SaveChangesAsync(); you need to set the state of the entities that you want to be modified. Somthing like:

var referralList = CustContext.Referrals.Where(d => d.UserId ==     membershipUser.Id);
foreach (Referral referral in referralList)
{
    referral.UserId = newUser.Id;
    CustContext.Entry(referral).State = System.Data.Entity.EntityState.Modified;
}
var result = await CustContext.SaveChangesAsync();

Upvotes: 1

Related Questions