假设我有一个包含Customer
,Employee
,Products
和CountyOfResidence
等对象的应用程序。这些对象映射到数据库中的表。
在应用程序中,我们希望能够通过GUI使用以前编写的存储过程搜索数据库。
这是一个命令模式有用的地方吗?
假设我们想了解客户和员工的平均年龄。在存储过程中使用一点动态SQL,我可以设想类似的情况
FilterByAge(tableNameForDynamicSQL,typeWereFilteringAgainst)
。
或类似FindPercentileRank(subject,tableName,type)
之类的东西。
使用GUI作为调用者并将存储过程作为命令的范例对我来说似乎很直观。从具有实践经验的人那里,这是一种在这种情况下会使用的模式吗?
答案 0 :(得分:2)
您所描述的内容听起来像Query Object Pattern,它与命令模式非常相似,但它特定于查询数据或对象。
您建议允许的自定义级别具有明确的潜在安全性和性能影响。例如,如果可以将任意表名发送到存储过程,并且它构建的查询针对未针对SQL调整好的表运行,那么您将面临暴露拒绝服务向量的风险。 / p>
我有一次类似的要求,而我发现的是,尽管需要更改搜索参数,但任何查询分类的返回列(您称之为“存储过程”)始终是相同的。我使用此信息为每组返回值创建单一类型的查询对象。这些允许极其灵活的查询,完全清理所有输入。它工作得很好。
另外,在构建查询对象类型时,您不仅限于存储过程。您可以在代码中创建参数化SQL,甚至可以构建可以运行的LINQ表达式树。
答案 1 :(得分:1)
通常,命令模式不会返回任何结果。通常,它将命令发送到系统并允许类封装命令的意图。
因此,它并不完全符合您的要求。您的问题更多是关于封装查询。但是,我认为您可以以相同的方式封装查询。
您可能希望查看Specification模式而不是Command。 Linq本身就是一种查询规范(使用表达式)。因此,如果您能够使用Linq to SQL或Entity Framework之类的东西,那么很多内容都是为您提供的。
答案 2 :(得分:1)
在存储过程中使用一点动态SQL
因此,您的UI将只是一个“存储过程参数编辑表单”,所有逻辑都将在SP中?我去过那里,不会很快再这样做。
我宁愿让我的UI链接到一些业务逻辑(在数据库之外,但在与数据库对话的DLL或web服务中),这可以构成来自某些输入参数的适当数据库调用。
使用ORM可以轻松完成此操作。
答案 3 :(得分:0)
如果您使用命令设计模式,应该有调用程序,命令和接收器,存储过程应链接到接收器而不是命令。
该命令可以在构造函数中调用一个接收器(调用存储过程),然后接收器在执行命令时执行实际任务。