题
我一直想知道是否有任何代码能够以某种对象树的形式表示 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),然后可以在构建阶段结束时“渲染”该语句。
解决方案
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
希望这有助于。
其他提示
Hibernate有其自己的Hibernate查询语言(HQL)表示SQL样构建为对象。
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;
一些帮助您入门的链接:
请参阅上面的,我已经看到不止一个程序员头沿着这条道路。 (我已经告诉不止一个程序员,我已经看到了一个以上的程序员......,但通常他们最终靠自己找出它如何工作的。)
我看到的困难是,你没有抽象的方式提供多少实质性增加的复杂性。你很可能需要知道SQL你会被无论如何结束了。
(至少到该图案作为表示在图中,在那里你直接指定条款。奥姆斯抽象远远超出的程度。)
您可以尝试的metadb 。有做了一些工作。 样品查询http://i3.codeplex.com/Project/下载/ FileDownload.aspx?项目名=&的metadb = DownloadId 11482
但是,如果你可以使用.NET 3.5,你可以使用LINQ。
在.NET中的LINQ确实相当多,你在说什么。
如果你还在使用.NET 2.0,并没有起对LINQ感动,然后我会创建一个基本的语句类,然后创建类允许的装饰图案。
这样,你可以继续添加你需要你的基地声明的内容。