我的查询类。你的意见?

时间:2009-08-10 14:46:25

标签: 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>();

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

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

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

以下是DAL呼叫示例:

OrdersDataTable orders = Orders.GetByOrderId( 1 )

和impl:

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

谢谢!

编辑:感谢大家的好评。很多人都建议使用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>();
    }

4 个答案:

答案 0 :(得分:3)

看起来你已经编写了一个非常好的小ORM(对象关系映射器),它具有Repository(或close)模式的实现。您还利用了名为Fluent Interfaces的设计模式,这是允许您进行的.Table .Fields相互级联。

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

编辑:我唯一可以看到改进的地方就是改变每个调用都是新查询的事实,也许改变你的代码使用依赖注入框架来注入正确的提供者并且当调用该对象时,它将为查询启动数据库事务。如果你的代码已经在Query类中内部完成了那个可以被称为“穷人的依赖注入”的内容,或者至少它是非常相似的(取决于你的实现),如果它已经为你工作并且你不打算真正成长你的数据库类型支持穷人的DI应该没问题。我不再喜欢任何用法中的新关键字,因为它通常会导致DI框架缓解的高级代码耦合(或者隐藏方法隐藏是一个糟糕的糟糕设计决策)。

回应Mark的回答,我通常不会成为代码生成的粉丝,但它似乎总是成为一个失败的点,但他确实有一个非常好的点来减少魔术字符串的数量参与其中。我会选择使用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>();
}

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

Inflector是一个免费的库(不记得是否是OSS),其中包含处理文本的功能,Pluralize方法将采用一个单词并使其成为...复数如果您无法猜测。这有用的地方就是当你有故事时你不能只去GetType()+“s”因为Storys不正确而且Inflector会正确地给你回“故事”。

答案 1 :(得分:1)

我通常会尝试远离这些功能性的做事方式。有时可能会混淆在问题出现时追踪问题。

我只使用LINQ并使用更易读的代码完成相同的任务。

答案 2 :(得分:0)

虽然我同意Linq的目的是为了做到这一点,但如果它适合您的要求,没有理由不建立自己的结构。

我会更进一步,使用代码生成来构建枚举类型或其他基于对象的权限,以减少对文字文本的需求。 (并减少错别字)

答案 3 :(得分:0)

这是一个有趣的练习,您的代码看起来确实非常易读和简洁。在生产环境中,除非有严重的需要,否则我可能会远离重新发明轮子。我和你的时间最好花在应用程序上创造价值,而不是在自定义ORM中添加功能,我们可以在其他经过实战考验的LINQ和NHibernate等软件包中免费获得这些功能。