C# 先使用EF代码的DDD-如何将它们组合在一起?

C# 先使用EF代码的DDD-如何将它们组合在一起?,c#,asp.net-mvc,ef-code-first,domain-driven-design,code-first,C#,Asp.net Mvc,Ef Code First,Domain Driven Design,Code First,我正在学习DDD开发几天,我开始喜欢它 我(想我)理解DDD的原理,您主要关注的是业务对象,您有聚合、聚合根、仅用于聚合根的存储库等等 我试图创建一个简单的项目,将DDD开发与代码优先方法相结合 我的问题是:(我正在使用asp.NETMVC) DDD业务对象将不同于代码优先对象? 即使它们可能是相同的,例如,我可以有一个Product业务对象,它包含所有规则和方法,我可以有一个Productcode-first(POCO)对象,它只包含我需要保存在数据库中的属性 如果问题1的答案为“true”,

我正在学习DDD开发几天,我开始喜欢它

我(想我)理解DDD的原理,您主要关注的是业务对象,您有聚合、聚合根、仅用于聚合根的存储库等等

我试图创建一个简单的项目,将DDD开发与代码优先方法相结合

我的问题是:(我正在使用asp.NETMVC)

  • DDD业务对象将不同于代码优先对象? 即使它们可能是相同的,例如,我可以有一个
    Product
    业务对象,它包含所有规则和方法,我可以有一个
    Product
    code-first(POCO)对象,它只包含我需要保存在数据库中的属性

  • 如果问题1的答案为“true”,那么我如何通知
    产品
    POCO对象业务对象
    产品
    的属性已更改,并且我必须更新它?我用的是“自动制版机”之类的东西? 如果答案是“不”,我完全迷路了

  • 你能给我举一个最简单(CRUD)的例子,说明如何将这两者结合起来吗

    谢谢

    Pluralsight课程:首先进入与EF代码结合的领域驱动设计的确切场景

    对于第一,我相信你可以用任何一种方式。这只是风格的问题。
    对于第二个问题,视频中的讲师通过两种方式对此进行解释。一种方法是在修改值时在客户端设置的每个类上都有一个“State”属性。DbContext然后知道要保留哪些更改。

    答案是否定的。EF代码的一个优点是它非常适合DDD,因为您必须手动创建业务对象,所以一定要使用EF模型来等效于DDD实体和值对象。不需要增加额外的复杂性,我认为DDD在任何地方都不建议这样做


    您甚至可以让您的实体来实现一个IEntity,并为对象赋值以实现IValue,此外,还可以遵循DDD模式的其余部分,即存储库,来执行与数据库的实际通信。您可以在.NET中找到这个非常好的示例应用程序,尽管它没有首先使用EF代码,但它仍然非常有价值:

    最近我做了类似的项目。我遵循本教程: 我是这样做的:我创建了空白解决方案,添加了项目:域、服务和WebUI

    简单地说,在域中我已经放置了模型(例如EF代码的类优先,方法等) 该服务用于域使用asp.NETWebAPI与世界(WebUI、MobileUI、其他站点等)进行通信 WebUi实际上是MVC应用程序(但模型在域中,所以它主要是VC)


    希望我已经帮助了

    更新我不再提倡使用“域对象”,而是提倡使用基于消息传递的域模型。有关示例,请参见

    对#1的回答是这要视情况而定。在任何企业应用程序中,您都会发现域中有两大类内容:

    直积垢

    这里不需要域对象,因为对象的下一个状态不依赖于对象的上一个状态。这些都是数据,没有行为。在这种情况下,可以在任何地方使用相同的类(即EF POCO):编辑、持久化、显示

    例如,在订单上保存帐单地址:

    public class BillingAddress {
      public Guid OrderId;
      public string StreetLine1;
      // etc.
    }
    
    另一方面,我们有

    状态机

    对于域行为和状态持久性,您需要有独立的对象(以及一个存储库)。域对象上的公共接口应该几乎总是所有void方法,并且没有公共getter。订单状态就是一个例子:

    public class Order { // this is the domain object  
      private Guid _id;
      private Status _status;
    
      // note the behavior here - we throw an exception if it's not a valid state transition
      public void Cancel() {  
        if (_status == Status.Shipped)
          throw new InvalidOperationException("Can't cancel order after shipping.")
        _status = Status.Cancelled;
      }
    
      // etc...
    }
    
    public class Data.Order { // this is the persistence (EF) class
      public Guid Id;
      public Status Status;
    }
    
    public interface IOrderRepository {
      // The implementation of this will:
      // 1. Load the EF class if it exists or new it up with the ID if it doesn't
      // 2. Map the domain class to the EF class
      // 3. Save the EF class to the DbContext.
      void Save(Order order); 
    }
    

    #2的答案是DbContext将自动跟踪EF类的更改。

    关于此主题的最新问题。 阅读Josh Kodroff的回答证实了我关于将存储库实现为实体框架DAL的想法

    将域对象映射到EF持久性对象,并在保存时让EF处理它。 检索时,让EF从数据库中获取并将其映射到域对象(聚合根)并将其添加到集合中


    这是存储库实现的正确策略吗?

    谢谢,但很遗憾,我无法从那里下载教程。(我没有信用卡要注册)这门Pluralsight课程有点乱,Julie将教你如何使用泛型存储库反模式,以及如何构建大量无用的抽象以使代码更加复杂。在过去的两年中,我学到了很多东西,除了最简单的CRUD场景外,我不再是泛型回购的粉丝!我将更新EF Enterprise课程,使用我自构建上一个课程以来一直在学习的DDD内容。课程加上EF现在支持更平滑的模仿,或者更少的抽象。希望您更喜欢udpate,ILICH.:)的确,代码首先允许您创建类,而不必担心数据库,但我不认为可以用域对象替换它们,域对象有很多私有属性、方法、只读字段,所有这些都不能通过EF正确映射。这就是为什么我认为你应该有两个对象你可以拥有你提到的所有东西,你可以在映射中忽略它们,或者将它们映射到不同的列名等等。。。映射是IRepository实现的一部分,并成为不会污染模型的实现细节。在所有情况下,好的设计都是关于管理复杂性的,因此即使您没有严格遵循DDD,您最好还是管理一个业务对象层。如果您有一个正在连接的遗留数据库,并且希望有一个干净的模型,那么唯一需要这种映射的时候就是映射