2

我对 DDD、工作单元、域服务、应用程序服务等的所有信息有点不知所措。我试图弄清楚一个不了解持久性的域模型最终是如何持久化的,特别是在单元的上下文中工作和实体框架。假设我有一个 Order 聚合根,我试图将其保留在我的持久性无知域模型(我的架构洋葱的核心)中:

public class Order : EntityBase
{
    public int Id { get; private set; }
    public int MarketplaceId { get; private set; }
    public int CustomerId {get; set;}
    public List<OrderItem> Items { get; private set; }
    public List<OrderComment> Comments { get; private set; }

    public void AddItem(OrderItem item) { /**add item**/ }
    public void AddComment(OrderComment comment) { /**add comment**/ }
    public override bool Validate() { /**validate**/ }
    public void Cancel() { /**cancel**/ }
}

假设我有一个更新 Order 实体上的属性的流程,例如它更改了与订单关联的 CustomerId。

我的域层中有一个 IOrderRepository,它将有一个具有如下功能的实现(在外层中):

Order GetOrder(int orderId)
{
    //get entity framework order, items, etc.
    //map to domain-layer order and return domain-layer order
}

void UpdateOrder(Order order)
{
    //get ENTITY FRAMEWORK order, order items, order comments, etc.
    //take DOMAIN order (passed in to this function), and update EF items fetched above
    //use a single EF unit of work to commit these changes
}

我的方法有问题。UpdateOrder 函数对于一个小改动来说似乎很重;但如果我的存储库不知道持久性无知域模型上的哪些项目已更改,我似乎也必须这样做。我应该在单独的存储库函数中处理每种类型的更新吗?更新市场(整数市场 ID),更新客户(整数客户 ID)?

当我输入这个时,我也在想......也许我上面的方式不是太重?如果我更改了一个属性,即使我正在执行上述所有操作,也许 Entity Framework 会识别出分配的值是相同的,并且只会将一个 db 列更新发送到 SQL?

如何获取我的 Order 域模型(获取非常简单),对其执行一些可能在范围内受限的操作,然后使用 Entity Framework 持久化模型?

4

3 回答 3

1

您需要研究工作单元模式。您的 UoW 会跟踪更改,因此当您从存储库获取订单并对其进行修改时,您调用 UnitOfWork.SaveChanges() 应该保留所有更改。

使用实体框架,您的 DbContext 基本上是工作单元,但我会围绕它创建一个更简单的界面,以便您可以将其抽象出来以便在更高层中使用。

关于 EF,我建议使用代码优先方法直接映射您的域实体。我还会关闭延迟加载和所有神奇的东西,这样你就可以完全控制并减少“惊喜”。

不幸的是,我不允许分享我们的代码,但我们可以在新的 EF6 Alpha 3 中有效地完成所有这些工作。我建议您查看 Microsoft Spain 的nlayerapp以获取一些实现示例。我不同意他们的许多设计决策(另请参阅此评论),但我认为您可以从 Entity Framework 部分中获得一些灵感。看看他们的工作单元实现,尤其是他们如何将其抽象出来以便在更高层中更容易使用,以及他们如何在应用程序服务中使用它。

我还建议考虑创建一个通用存储库,以避免在您的聚合特定存储库中重复大量逻辑。MS 西班牙在这里有一个,但你也应该看看这个线程

于 2013-05-15T09:09:29.563 回答
-1

请看一下这个SO question,我在其中举例说明了我是如何实现 UoW 和存储库的。

正如@Tommy Jakobsen 告诉您的那样,您的域实体应该是您的 EF 实体,它将避免您添加无用的映射层。

希望有帮助!

于 2013-05-15T14:39:32.650 回答
-1

您可以查看 ASP.NET Boilerplate 的工作单元实现:http ://www.aspnetboilerplate.com/Pages/Documents/Unit-Of-Work

它是开源项目,您可以检查代码。此外,您可以直接使用它。

于 2015-03-03T07:13:42.860 回答