将这些方法从EF 6转换为EF Core

时间:2019-04-25 09:19:49

标签: c# entity-framework .net-core

我一直在尝试实现一种解决方案,以在断开连接的情况下正确设置实体状态(在该情况下,每次调用NetCore API都会加载一个新的DBContext实例)。

Julie Lehrmann的Book Programming Entity Framework中有一个解决方案,提出了我想实现的解决方案。不幸的是,它是为EF 6而编写的。

如何为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;
}

最后是这种方法

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;
    }
  }
}

非常感谢您帮助我将其翻译为EF Core兼容代码!

原始代码可在此处找到 https://www.oreilly.com/library/view/programming-entity-framework/9781449331825/ch04.html

1 个答案:

答案 0 :(得分:1)

EF 6.3 will target .NET Standard 2.1起,您很快将不再需要将它们迁移到EF Core。

要使用此功能,您需要将项目迁移到库的.NET Core 3.0或.NET Standard 2.1。

.NET Core 3.0将于今年下半年发布,或者像现在一样使用预览SDK可能会带来一些风险。