是否有OO模型来生成SQL?

时间:2009-02-02 20:15:55

标签: c# .net sql semantics

我一直在想是否有任何代码能够以某种对象树的形式表示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语句(多个连接,多个连接)的情况,然后可以在构建阶段结束时“呈现”。

7 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分: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;

一些可以帮助您入门的链接:

答案 2 :(得分:2)

见上文,我看到不止一个程序员走这条路。 (而且我告诉不止一个程序员我见过不止一个程序员......但通常他们最终会发现自己的工作效果如何。)

我看到的困难在于你在不提供抽象方式的情况下增加了实质性的复杂性。你几乎需要知道你最终会得到什么样的SQL。

(至少在你的插图中表示模式的程度,你直接指定了这些条款.ORMs抽象远不止于此。)

答案 3 :(得分: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

希望这有帮助。

答案 4 :(得分:1)

您可以尝试MetaDb。做了一些工作。 Sample query http://i3.codeplex.com/Project/Download/FileDownload.aspx?ProjectName=metadb&DownloadId=11482

但是如果你可以使用.NET 3.5,你可以使用LINQ。

答案 5 :(得分:0)

在.Net中,Linq几乎就是你所说的。

答案 6 :(得分:0)

如果您仍在使用.NET 2.0并且没有向前移动到LINQ,那么我将创建一个基本语句类,然后创建允许装饰器模式的类。

通过这种方式,您可以继续添加基本语句所需的内容。