Reputation: 724
I have been trying to implement a solution to properly set the State on Entities in a Disconnected scenario (where a new instance of the DBContext is loaded for every call to the NetCore API).
There is a solution in the Book Programming Entity Framework by Julie Lehrmann that proposes a solution I would like to implement. Unfortunately, it is written for EF 6.
How do I write these Methods for EF Core?
public BreakAwayContext()
{
((IObjectContextAdapter)this).ObjectContext
.ObjectMaterialized += (sender, args) =>
{
var entity = args.Entity as IObjectWithState;
if (entity != null)
{
entity.State = State.Unchanged;
entity.OriginalValues =
BuildOriginalValues(this.Entry(entity).OriginalValues);
}
};
}
private static Dictionary<string, object> BuildOriginalValues(
DbPropertyValues originalValues)
{
var result = new Dictionary<string, object>();
foreach (var propertyName in originalValues.PropertyNames)
{
var value = originalValues[propertyName];
if (value is DbPropertyValues)
{
result[propertyName] =
BuildOriginalValues((DbPropertyValues)value);
}
else
{
result[propertyName] = value;
}
}
return result;
}
And lastly this method
private static void ApplyChanges<TEntity>(TEntity root)
where TEntity : class, IObjectWithState
{
using (var context = new BreakAwayContext())
{
context.Set<TEntity>().Add(root);
CheckForEntitiesWithoutStateInterface(context);
foreach (var entry in context.ChangeTracker
.Entries<IObjectWithState>())
{
IObjectWithState stateInfo = entry.Entity;
entry.State = ConvertState(stateInfo.State);
if (stateInfo.State == State.Unchanged)
{
ApplyPropertyChanges(entry.OriginalValues,
stateInfo.OriginalValues);
}
}
context.SaveChanges();
}
}
private static void ApplyPropertyChanges(
DbPropertyValues values,
Dictionary<string, object> originalValues)
{
foreach (var originalValue in originalValues)
{
if (originalValue.Value is Dictionary<string, object>)
{
ApplyPropertyChanges(
(DbPropertyValues)values[originalValue.Key],
(Dictionary<string, object>)originalValue.Value);
}
else
{
values[originalValue.Key] = originalValue.Value;
}
}
}
Thank you so much for helping me translate this into EF Core compatible Code!
Original Code can be found here https://www.oreilly.com/library/view/programming-entity-framework/9781449331825/ch04.html
Upvotes: 0
Views: 1116
Reputation: 4775
You will soon no longer need to migrate them to EF Core since EF 6.3 will target .NET Standard 2.1.
To make use of this, you need to migrate your project to .NET Core 3.0 or .NET Standard 2.1 for libraries.
.NET Core 3.0 will be released in the second half of this year, or you could take a little bit risk using the preview SDK as for now.
Upvotes: 1