Nicholas Nicholas - 24 days ago 7
C# Question

EntityFramework not saving new data on entity

I have a question regarding updating existing users with new data using EntityFramework and Domain Models. Or actually more like an issue.

When Adding a new Order to a User, after converting said

Order
to an
OrderEntity
then adding it to the
UserEntity
, and persisting it to the Database, the given Order is not saved.

So we have an
IUserModel
here:

public interface IUser
{
int ID { get; }
List<IOrder> Orders { get; }
}


And an entity
UserEntity
here:

public class UserEntity
{
int ID { get; set; }
public List<OrderEntity> Orders { get; set; }
}


We have a service called
PersistenceService
here:

public async Task<bool> UpdateInformation(IUser user)
{
using (var databaseContext = new DatabaseContext())
{
var userEntity = await database.Users.Include(u => u.Orders)
.FirstOrDefaultAsync(x => x.ID == user.ID);

userEntity.Orders = user.Orders.ToEntity(); // Extension (convert to entity)
databaseContext.Entry(userEntity).State
= EntityState.Modified; // Do we need this?
databaseContext.Entry(userEntity.Orders).State
= EntityState.Modified; // Do we need this?

await databaseContext.SaveChangesAsync();
}
}


Tables in the Database look like this:

Orders User
-------- --------
int ID int ID
Money Price
int UserId -- foreign key to user that owns this order


Edit:
At some point when a user wants to create an Order we call do this:

public async void AddNewOrder(IOrder order)
{
IUser user = GetActiveUser(); // This just return an IUser
var persistenceService = GetPersistenceService(); // returns instance of persistence service

user.Orders.Add(order);
await persistenceService.UpdateInformation(user);
}


Edit 09-11-2016:
After more debugging, it looks like the line:

await persistenceService.UpdateInformation(user);


Never returns, this doesn't change when you change the code to run synchronously either. So it's no threading problem.

Answer

You're overriding the orders list in this statement:

userEntity.Orders = user.Orders.ToEntity(); // Extension (convert to entity)

I'm pretty sure that's what messes stuff up. If you change the line to:

userEntity.Orders.AddRange(user.Orders.ToEntity());

I believe it should work. This does however always add the all the orders to the customer as new. If this is not what you want, you can use a combination of Add and Remove calls to update the Orders collection instead of just adding them. But to just test if it saves anything you can just use AddRange() for now.

In addition, you shouldn't set the State of the entities unless you're attaching them (which you aren't). So drop these lines

     databaseContext.Entry(userEntity).State 
                  = EntityState.Modified; // Do we need this?
     databaseContext.Entry(userEntity.Orders).State 
                  = EntityState.Modified; // Do we need this?
Comments