首页 > 解决方案 > 将这些方法从 EF 6 转换为 EF 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

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

解决方案


您很快将不再需要将它们迁移到 EF Core,因为EF 6.3 将面向 .NET Standard 2.1

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

.NET Core 3.0 将在今年下半年发布,或者您可以像现在一样使用预览版 SDK 冒一点风险。


推荐阅读