Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是EF实体或域对象的规范模式_C#_Entity Framework_Domain Driven Design_Specification Pattern - Fatal编程技术网

C# 是EF实体或域对象的规范模式

C# 是EF实体或域对象的规范模式,c#,entity-framework,domain-driven-design,specification-pattern,C#,Entity Framework,Domain Driven Design,Specification Pattern,我是领域驱动设计的新手,所以如果这个问题很琐碎,请原谅。我正在阅读规范模式,我相信我理解它的意图。web上的大多数示例显示了它在两个地方的用法: 内部存储库方法 域内服务/应用程序服务 但这只有在EF实体和域对象相同的情况下才有效。我猜这不是一个好的实践(使用EF实体作为域对象)。 现在我的问题是—— 我们应该为域对象和EF实体编写不同的规范规则,还是有一种方法可以为这两个实体重用相同的规则?我想如果我们不使用c#表达式并使用反射,我们可以以某种方式实现。请记住,在使用EF存储库时,您已经有了默

我是领域驱动设计的新手,所以如果这个问题很琐碎,请原谅。我正在阅读规范模式,我相信我理解它的意图。web上的大多数示例显示了它在两个地方的用法:

  • 内部存储库方法

  • 域内服务/应用程序服务

  • 但这只有在EF实体和域对象相同的情况下才有效。我猜这不是一个好的实践(使用EF实体作为域对象)。 现在我的问题是——


    我们应该为域对象和EF实体编写不同的规范规则,还是有一种方法可以为这两个实体重用相同的规则?我想如果我们不使用c#表达式并使用反射,我们可以以某种方式实现。

    请记住,在使用EF存储库时,您已经有了默认选项-让存储库返回
    IQueryable
    ,而不是
    IEnumerable
    。许多程序员对此感到害怕,但如果这样做,LINQ将成为基础架构层的规范

    然后,在域层中,您可以应用规范和规则模式来封装应该测试域对象的条件和规则


    还有其他技术,但这种组合是我通常在项目中应用的。

    这是一个我非常关心的话题。(直接答案如下)规范模式是不可知的。它所做的只是确定您定义(指定)的条件是否满足。这在两个地方都很有用。我看到了规范的两个主要好处:它命名您的业务规则,并隐藏(封装)您的实现。接下来的好处是,如果您希望或提供易于理解的查询或规则列表,您可以锁定存储库

    应用于域对象的规范与用作查询的规范略有不同,但非常接近。“QuerySpecification”中应该包含查询语言,目标存储库实现(EF)可以在数据库中执行,并返回0个或更多匹配项

    应用于域对象时,它更常用于检查特定对象是否“符合规范”或筛选列表中的适用对象(排除或包含)。用法看起来不同,或者是同一概念的不同方面

    我恭敬地不同意佐兰的建议。返回IQueryable意味着您正在为应用程序代码(可能是其他人的应用程序)提供直接查询数据存储的能力。懒惰与急切的加载也成了一个真正的纠结。我认为,您会失去封装和实现隔离

    还要记住,EF表示存储库和UnitOfWork的实现。DbContext是工作单元,而DbSet是存储库。您应用自己的DDD接口的目标是确保您的域不依赖于EF实现,因此您的集成代码应该非常小

    所以,直接回答

    我建议向您的存储库接口添加一个方法,该方法接受IQuerySpecification并返回T。您的实际规范是您域的一部分。这些是组织所需数据组合的规则。您可以将它们放在“共享内核”(库)中,或者根据您的需要将它们驻留在应用程序中

    请注意,理想情况下,通过使用查询规范,可以消除经常弹出的所有特殊用途存储库函数,因为规范将被查询的内容与查询分开。埃里克·埃文斯写得更好:

    规范的中心思想是将如何进行的陈述分开 要匹配候选对象,请从匹配的候选对象 反对。除了在选择上有用外,它也是有价值的 用于验证和按订单建造 ()


    另请参见

    为什么投反对票?我已经从领域驱动设计的角度对基础设施和领域中的规范进行了精确的解释。有很多在线资源讨论了从存储库中公开IQueryable的利弊。关于规范模式,我在这里的一门Pluralsight课程中有一个模块:请注意,当返回IQueryable时,您违反了“不要重复您自己”和“单一责任”原则。您刚才说的是,
    DbContext
    的目的是为了打破僵局和SRP。你能详细说明一下吗?马特的链接对新手来说是一个很好的起点!