Let's say we have a MyDbContext having DbSet<MyEntity> in it. I'm trying to implement the following scenario (as I found out it is called disconnected scenario or disconnected mode):
- I obtain
List<MyEntity>from database (it can be simply all records viaDbContext.MyEntities.ToList()or records by some filter condition - it doesn't matter). - Then those entities are passed to some UI where user can change properties. His behaviour is unpredictable: he can change every property of every entity or he can change only one property of a single entity (he even can perform no changes at all).
- After that I need to pass the updates to database.
To implement that scenario I've found for me two possible solutions:
1) Keep connection open during the whole scenario. So it will work like this:
MyDbContext.Database.Connection.Open();
List<MyEntity> EntitiesList = MyDbContext.MyEntities.ToList();
//passing EntitiesList to the UI, where user can change them
EntitiesList[0].SomeStringProperty = "123";
//change some other properties here
//saving changes to database some time later
MyDbContext.SaveGhanges();
MyDbContext.Database.Connection.Close();
But in this solution database connection persists open too long. It shouldn't be open when UI is working (because user can change entities during several hours for example).
2) Close connection after obtaining List<MyEntity> and open
connection again when passing updates to database. So it will work
like this:
MyDbContext.Database.Connection.Open();
List<MyEntity> EntitiesList = MyDbContext.MyEntities.ToList();
MyDbContext.Database.Connection.Close();
//passing EntitiesList to the UI, where user can change them
EntitiesList[0].SomeStringProperty = "123";
//change some other properties here
//saving changes to database some time later
MyDbContext.Database.Connection.Open();
foreach(var entity in EntitiesList)
{
//Attach updated entity and make context know that it is modified
MyDbContext.MyEntities.Attach(entity);
MyDbContext.MyEntities(entity).State = EntityState.Modified;
}
MyDbContext.SaveGhanges();
MyDbContext.Database.Connection.Close();
But in this solution I think that absolutely all properties of all entites were modified. It results in huge database update overhead.
Another choice will be to write MyEntityWrapper class which will track all changes performed by user and will know which properties needs to be updated. So I can change my code above to this one:
foreach(var entity in EntitiesList)
{
//Attach updated entity and make context know which properties are modified
MyDbContext.MyEntities.Attach(entity);
MyDbContext.Entry(entity).Property(e => e.SomeStringProperty).IsModified = true;
//mark other changed properties
}
So - is there some more elegant solution, can I update only changed properties without writing MyEntityWrapper class? Can I simply tell DbContext: "here is some List<MyEntity> - take it, determine which properties differs from that values in a database and update those values"?
BTW. If it matters - I'm working with SQLite database via Devart dotConnect for SQLite + EntityFramework 6.0.1