【问题标题】:CRUD operations with connected POCOs instead of disconnected POCOs in EF code first首先在 EF 代码中使用连接的 POCO 而不是断开的 POCO 进行 CRUD 操作
【发布时间】:2013-12-09 18:56:30
【问题描述】:

我有一个经典的 3 层项目,它有这些层:

  • UI(WinForm 项目)
  • BLL
  • DAL(使用 EF 代码优先)

我的实体已断开连接POCOs,我使用它们在层之间传递数据并使用它们绑定到 UI 控件。

我将一些相关实体的图表加载到 UI(例如Order,每个OrderLines 和Product OrderLine),用户可以添加一些新实体,编辑一些其他实体并删除一些其他实体在此图中,然后将此图发送到 DAL 以将此更改持久保存到 DB。

我想将所有这些 CRUD 操作应用到一个 transaction 中。因此,对于这个要求,并且因为我的POCOs 已断开连接,我使用以下State enum 为我的BaseEntity 类保持其状态在客户端(所有其他实体继承自BaseEntity):

public enum States
    {
        Unchanged,
        Added,
        Modified,
        Deleted
    }

在 DAL 中,当我想保留这个更改的对象图时,因为这个实体图与 DbContext 断开连接,我应该将我的图的根附加到创建的 DbContext 并且因为在将根附加到所有 DbContext 状态之后DbContext 中的条目将是 Added,我应该将 DbContext 中每个 EntryState 与图表中的实体 State 同步,所以我使用这些方法来执行此操作:

public static EntityState ConvertState(BaseEntity.States state)
{
    switch (state)
    {
        case BaseEntity.States.Added:
            return EntityState.Added;
        case BaseEntity.States.Modified:
            return EntityState.Modified;
        case BaseEntity.States.Deleted:
            return EntityState.Deleted;
        default:
            return EntityState.Unchanged;
    }
}

public void ApplyChanges<TEntity>(TEntity root) where TEntity : BaseEntity
{
   _dbContext.Set<TEntity>().Add(root);
    foreach (var entry in _dbContext.ChangeTracker
    .Entries<BaseEntity>())
    {
        BaseEntity stateInfo = entry.Entity;
        entry.State = ConvertState(stateInfo.State);
    }
}

如您所见,我在 EF 之外做了很多事情并且不使用 EF 功能,因为我的 POCO 已断开连接。

有什么方法可以应用这些批量 CRUD 方案,而无需断开我的 POCOs 与 DbContext 的连接?

【问题讨论】:

  • 为什么不使用经典实体、视图模型和像 automapper 这样的映射器来进行翻译?然后,您将获得像 EF 这样的 ORM 的所有功能。你在这里有点重新发明轮子,我不清楚为什么。
  • @Maess 是对的,如果您使用视图模型,您将能够将所有更改应用到上下文并一次保存。然后所有状态将由上下文自动处理。您的另一个选择是在您的 UI 中创建和使用上下文,但这会产生非常强烈的代码气味。
  • @Maess : 我可以用这种方法应用这个场景吗?
  • 您可以使用它来确定实体的上下文状态,是的。但如果你使用 Onion 架构,调用适当的存储库方法会将其抽象掉。
  • @Maess : 这个方法有什么好的样本吗?

标签: c# entity-framework poco crud dbcontext


【解决方案1】:

对于断开连接的 POCO 实体,我在坚持时遵循了这种模式。

  • 从数据库中获取连接实体图。
  • 将断开连接的图形映射到连接的图形。
  • 保持连通图。

目前,您正试图通过 UI 一直跟踪更改,而这些更改在您准备好坚持时可能相关也可能不相关,这充其量是繁琐的。我发现在持久化之前从数据库中获取最新的实体效果更好。

这还使您能够在执行映射时检查并发问题。

【讨论】:

  • 但是在你的方法中(在第一步中)我必须从 db 中获取连接的实体图,并且这个事务闻到某种类型的重复。
  • 最后,我用了这个方法,用graphdiff :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-15
  • 2012-03-19
  • 2011-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多