Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.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# 使用原始sql进行存储库和查询?_C#_Domain Driven Design_Repository_Repository Pattern_Ddd Repositories - Fatal编程技术网

C# 使用原始sql进行存储库和查询?

C# 使用原始sql进行存储库和查询?,c#,domain-driven-design,repository,repository-pattern,ddd-repositories,C#,Domain Driven Design,Repository,Repository Pattern,Ddd Repositories,我正在努力理解如何最好地查询存储库 现在让我陷入困境的三个因素是: 返回数据类型 要对其运行查询的列 要返回的记录数 第1点 关于问题一: 我有很多方法的存储库,它们返回实体和标量值的组合。这似乎导致了“方法爆炸”。我应该总是返回实体对象吗?我应该如何查询只需要一列的对象 第2点 在运行查询时,即使我只需要一列或两列,我是否应该包括表中的每一列?如果我为此创建特定的查询,将导致存储库中出现更多的方法 第3点 我应该如何为查询提供条件?我读过有关规范的内容,但我的理解是,您可以循环遍历返回的记录,

我正在努力理解如何最好地查询存储库

现在让我陷入困境的三个因素是:

  • 返回数据类型
  • 要对其运行查询的列
  • 要返回的记录数
  • 第1点

    关于问题一:

    我有很多方法的存储库,它们返回实体和标量值的组合。这似乎导致了“方法爆炸”。我应该总是返回实体对象吗?我应该如何查询只需要一列的对象

    第2点 在运行查询时,即使我只需要一列或两列,我是否应该包括表中的每一列?如果我为此创建特定的查询,将导致存储库中出现更多的方法

    第3点 我应该如何为查询提供条件?我读过有关规范的内容,但我的理解是,您可以循环遍历返回的记录,并过滤掉传递到新集合中的记录。就性能而言,这似乎不是一个好主意。现在我只是在Repo中创建了一个新方法,比如getNameById(),它封装了条件

    请不要说我没有使用ORM,我的存储库中只有原始sql

    更新

    第1点: 根据答案和更多的研究,这是一个好的实现吗

    现在,我有一个大型存储库,它返回标量和实体类型对象的混合(都是相同的实体)。我想,如果我只使用一个GetUser(userId)方法,而忘记编写只返回单列值的方法,我可以大大减少这种情况

    例如,如果我需要返回用户名,我可以调用GetUser(userId)方法,该方法将用户对象分解,然后在服务层将其过滤为用户名

    另一种方法是使用某种QueryBuilder类,我可以将其传递到存储库中,对其进行解析以生成正确的sql

    第2点

    回过头来看,这与第一点非常相似,我当前的解决方案是只获取所有表字段。这是性能和可维护性之间的折衷

    第3点

    我需要提供某种where子句。我不确定通过规范或仅仅是sql字符串这样做是否有意义。我目前的解决方案是为这些类型创建新方法,但我希望存储库有更通用的方法


    总的来说,仍在研究这个。。。我很想听到更多关于这方面的信息,或者与书籍或参考文献的链接,这些链接将这一切联系在一起。

    首先,您还没有真正解释您使用这些查询的目的。很可能是为了满足用户界面的需要。如果是这样,就不需要跳过所有这些障碍(服务->存储库->域->dto->客户端),只要尽可能直接地查询数据库即可。您知道什么,您是否可以查询标量或只查询所需的列的问题已经不复存在了。只需使用普通sql并返回所需内容。不要制造导致摩擦的抽象概念

    我有很多方法的存储库,它们返回实体和标量值的组合。这似乎导致了“方法爆炸”。我应该总是返回实体对象吗?我应该如何查询只需要一列的对象

    您可以像处理其他SRP冲突一样处理存储库方法爆炸。您可以为同一实体创建另一个存储库。看看这个问题,你会发现一个类似的问题

    在运行查询时,即使我只需要一列或两列,我是否应该包括表中的每一列?如果我为此创建特定的查询,将导致存储库中出现更多的方法

    这不是DDD问题。域驱动设计不处理“行和列”。加载多少数据来“补充”域对象总是有冗余的,但您必须衡量这是否真的会影响性能。如果这确实是一个性能瓶颈,那么它可能是不正确的域模型的症状

    我应该如何为查询提供条件?我读过有关规范的内容,但我的理解是,您可以循环遍历返回的记录,并过滤掉传递到新集合中的记录。就性能而言,这似乎不是一个好主意。现在我只是在Repo中创建了一个新方法,比如getNameById(),它封装了条件

    这也是一个数据访问问题。DDD中没有任何内容表明存储库无法将规范转换为SQL查询。是这样做还是遍历内存中的记录取决于您(只要存储库使用者只看到规范和存储库,而不知道实际实现)


    关于“原始SQL与DDD中的ORM”,您可能会发现这一点很有趣。

    我同意Dmitry所说的一切,但可能认为您应该阅读一下

    在开始使用DDD时,我曾经问过类似的问题(关于“方法爆炸”,而不是SQL问题),这让我想到了。就我个人而言,如果没有DDD,我真的看不出它有多实用,而且它在查询数据时回答了很多这类问题。根据其原则,我建议:

  • 提交事务时仅使用域存储库。也就是说,您不使用存储库在UI中显示数据。只有在需要对聚合执行操作时,才能从存储库中获取聚合
  • 存储库只返回聚合,而不是单独返回单个实体。现在这是有意义的,因为我们只在事务意义上使用存储库,实体只能通过原子操作进行变异,并作为一个整体由聚合持久化
  • 您可以创建单独的存储库(或“查询服务”),为您需要的任何数据提供定制的查询和数据类型。这些可以恢复