我的查询类.你的意见?

Ste*_*eve 6 c# ado.net

我只是想分享这个Query类,并对它有所了解.Query类有助于对dbconnection执行查询.我没有包含实现,发布有点多.这是一个示例调用,你会明白这个想法:

OrdersDataTable table = 
   new Query(connection)
   .Table("Orders")
   .Fields("OrderID,CustomerID,Description,Amount")
   .GreaterThan("OrderID", 1000)
   .OrderBy("OrderID")
   .Execute<OrdersDataTable>();
Run Code Online (Sandbox Code Playgroud)

以下是我喜欢上课的原因:

  • 无需编写ADO.NET命令代码.调用此类占用的行数少于ADO.NET等效行.
  • 每个成员函数都返回此值,因此可以将多个调用链接在一起.我不确定这个模式是否有名称.你知道吗?
  • 处理MySql,OleDb和SqlServer方言.
  • 对于我来说,似乎比ADO.NET等等更易读.
  • 通话顺序无关紧要.所有参数都在内部集合中缓冲,并在调用Execute时读取.
  • 我的场景要求我与多个数据库产品进行通信,因此我希望以通用方式编写查询一次,并传递给定的连接.利用存储过程等特定于数据库的功能会有很多麻烦.

我有一个内部使用此类的DAL.UI将调用DAL,传递一些查询参数并返回DataTable.该类确实帮助减少了LOC的DAL实现,并使其更具可读性.

这是一个DAL调用示例:

OrdersDataTable orders = Orders.GetByOrderId( 1 )
Run Code Online (Sandbox Code Playgroud)

并且impl:

public static OrdersDataTable GetByOrderId( int id )
{
    return  
       new Query(connection)
       .Table("Orders")
       .Fields("OrderID,CustomerID,Description,Amount")
       .Equals("OrderID", id)
       .Execute<OrdersDataTable>();
}
Run Code Online (Sandbox Code Playgroud)

谢谢!

编辑:感谢大家的好评.很多人都建议使用LinqToSql.我没有选择Linq,因为Microsoft目前只支持Sql Server.我需要查询Jet,MySql和Sql Server表.

有人询问如何构造AND和OR子句.这是每个例子

//and example
    public static OrdersDataTable GetByOrderIdAndCustomerId( int orderId, int customerId )
    {
        return  
           new Query(connection)
           .Table("Orders")
           .Fields("OrderID,CustomerID,Description,Amount")
           .Equals("OrderID", orderId)
           .Equals("CustomerID", customerId)
           .Execute<OrdersDataTable>();
    }

//or example
    public static OrdersDataTable GetByOrderIdOrCustomerId( int orderId, int customerId )
    {
        return  
           new Query(connection)
           .Table("Orders")
           .Fields("OrderID,CustomerID,Description,Amount")
           .OrBegin
           .Equals("OrderID", orderId)
           .Equals("CustomerID", customerId)
           .OrEnd
           .Execute<OrdersDataTable>();
    }
Run Code Online (Sandbox Code Playgroud)

Chr*_*sic 3

看起来您已经编写了一个非常好的小型 ORM(对象关系映射器),其中包含存储库(或接近)模式的实现。您还利用了称为 Fluent Interfaces 的设计模式,该模式允许您进行 .Table .Fields 相互级联。

所有这 3 个模式都非常适合包含在现代软件系统设计中,因为您已经注意到它们极大地减少了 LOC、增强了可维护性并极大地提高了测试能力。我还喜欢您构建的功能能够正确使用泛型返回强类型对象。

编辑:我认为需要改进的唯一可能的领域是改变每个调用都是一个新查询的事实,也许更改您的代码以使用依赖注入框架,该框架将注入正确的提供程序,并且当调用对象时它将启动用于查询的数据库事务。如果你的代码已经在 Query 类内部做了很多这样的事情,可以称为“穷人的依赖注入”,或者至少它非常相似(取决于你的实现),如果它已经为你工作并且你不打算真正成长根据您的数据库类型支持,Poor man's DI 应该就可以了。我只是不再喜欢 new 关键字的任何用法,因为它通常会导致 DI 框架减轻的高水平代码耦合(或者隐藏方法是一个糟糕的设计决策)。

针对马克的回答,我通常不喜欢代码生成,它似乎总是成为一个失败点,但他确实有一个很好的观点来减少所涉及的魔法字符串的数量。不过,我会选择使用 Lambda 运算符和表达式来处理此问题,这样您就可以实现此目的:

public static OrdersDataTable GetByOrderId( int id )
{
    return  
       new Query(connection)
       .Table(x => Inflector.Pluralize(x.GetType())
       .Fields(x=> { x.OrderID, x.CustomerID, x.Description, x.Amount })
       .Equals(x=>x.OrderID, id)
       .Execute<OrdersDataTable>();
}
Run Code Online (Sandbox Code Playgroud)

这将消除所有魔术字符串重构问题,使您能够更轻松地利用 Microsoft 内置的重构工具或 Resharper 的(当然,resharper 可以在重构期间找到魔术字符串)。

Inflector 是一个免费的库(不记得它是否是 OSS),其中包含处理文本的功能,Pluralize 方法将采用一个单词并将其...复数(如果您猜不出来)。这很有用的地方是,当您有类似 Story 的情况时,您不能只使用 GetType() +“s”,因为 Storys 不正确,而 Inflector 将正确返回您“Stories”。