1

我一直想知道是否有任何代码可以以某种对象树的形式表示 SQL,这些对象树可以组装、修改然后最终呈现为有效的 SQL?

从我的头顶上看,它可能看起来像那样......

var stmnt = new Statement();
stmnt
  .AddMaster("Customer")
  .Show("Firstname, "Lastname")
  .AddJoin("Address", "ID", "CustomerID")
  .Show("Street", "City");
stmnt.WhereStatement()
  .AddParameter("Address.City", Op.Equal);

string sql = stmnt.Generate();
// select a.FirstName, a.LastName, b.Street, b.City
// from Customer a
// join Address b on b.CustomerID = a.ID
// where b.City = :p1

这只是一个例子,外面的事情可能完全不同,但是是的,我很想听听这方面的情况。

更新:

我知道使用 ORM 技术从数据库中获取结果的多种可能性,但我追求的是 SQL 本身的模型。我知道抽象级别非常低,但它可能允许多个协作者可以处理 SQL 语句(多个连接,多个 where),然后可以在构建阶段结束时“渲染”。

4

7 回答 7

5

Hibernate 有自己的 Hibernate 查询语言 (HQL),它将类似 SQL 的构造表示为对象。

于 2009-02-02T20:16:45.600 回答
2

一个 OR-Mapper,例如 Microsoft 的LINQ

这里有些例子:

from c in customers
where c.LastName.StartsWith("A")
select c

//

var q = from c in db.Contact
           where c.DateOfBirth.AddYears(35) > DateTime.Now
           orderby c.DateOfBirth descending
           select c;

一些帮助您入门的链接:

于 2009-02-02T20:21:13.143 回答
2

见上文,我见过不止一个程序员走上这条路。(而且我告诉不止一位程序员,我见过不止一位程序员……但通常他们最终会自己发现它的工作原理。)

我看到的困难是您在没有提供太多抽象方式的情况下增加了相当大的复杂性。您几乎需要知道无论如何您最终会使用什么 SQL。

(至少在您的插图中表示的模式的程度上,您直接指定子句。ORM 的抽象远不止于此。)

于 2009-02-02T20:22:58.223 回答
2

Python 包 SQLAlchemy 有一个 ORM 层,但它也有一个 SQL 生成层。

[我知道你标记了这篇文章 c# 和 .net,但我想你可能想看看还有什么]

这是一些示例代码:

from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
from sqlalchemy.sql import select

metadata = MetaData()

# Make a basic customer table.
Customer = Table('Customer',
                 metadata,
                 Column('ID', Integer, primary_key=True),
                 Column('FirstName', String),
                 Column('LastName', String))

# Make a basic address table
Address = Table('Address',
                metadata,
                Column('ID', Integer, primary_key=True),
                Column('City', String),
                Column('Street', String),
                Column('CustomerID', None, ForeignKey('Customer.ID')))


# Generate some sql
stmt = select([Customer.c.FirstName,
               Customer.c.LastName,
               Address.c.Street,
               Address.c.City],
              from_obj=Customer.join(Address),
              whereclause=Address.c.City == 'Wellington')

# Display
print stmt
# output:
SELECT "Customer"."FirstName", "Customer"."LastName", "Address"."Street", "Address"."City" 
FROM "Customer" JOIN "Address" ON "Customer"."ID" = "Address"."CustomerID" 
WHERE "Address"."City" = :City_1

# note that SQLAlchemy picked up the join condition from the foreign key.
# you can specify other join conditions if you want.

通常,您将通过使用 SQLAlchemy 连接到数据库来执行该语句。然后你可以这样做:

for row in stmt.execute():
    print 'Name:', row.c.FirstName, row.c.LastName, 'City:', row.c.City

希望这可以帮助。

于 2009-02-02T22:25:14.997 回答
1

您可以尝试MetaDb。有一些工作已经完成。 示例查询 http://i3.codeplex.com/Project/Download/FileDownload.aspx?ProjectName=metadb&DownloadId=11482

但如果您可以使用 .NET 3.5,则可以使用 LINQ。

于 2009-02-02T20:19:27.310 回答
0

在 .Net 中,Linq 几乎可以满足您的要求。

于 2009-02-02T20:18:54.380 回答
0

如果您仍在使用 .NET 2.0 并且尚未继续使用 LINQ,那么我将创建一个基本语句类,然后创建允许使用装饰器模式的类。

这样,您就可以继续将您需要的内容添加到基本语句中。

于 2009-02-02T20:19:26.157 回答