简体   繁体   English

是否有用于生成SQL的OO模型?

[英]Are there OO models to generate SQL?

I have been wondering whether there is any code out there that enables representing SQL in the form of some object tree that can be assembled, modified and then finally rendered to valid SQL? 我一直想知道是否有任何代码可以以某种对象树的形式来表示SQL,这些对象树可以被组装,修改然后最终呈现为有效的SQL?

Off the top of my head it could look something like that... 在我的头顶上,看起来可能像这样...

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

This is just an example and the thing out there may work totally different, but yes, I'd love to hear what is out tere in that respect. 这只是一个例子,那里的事情可能完全不同,但是是的,我很想听听这方面的事情。

UPDATE: 更新:

I am aware of the numerous possibilities of using ORM technologies to get my results from the DB, but I was after a model for the SQL itself. 我知道使用ORM技术从数据库获取结果的可能性很多,但是我一直在追求SQL本身的模型。 I know that the level of abstraction is pretty low, but it could possibly allow a situation where multiple collaborators can work on an SQL statement (multiple joins, multiple wheres) which can then be "rendered" at the end of the build-Phase. 我知道抽象水平很低,但是它可能允许多个协作者可以处理一条SQL语句(多个联接,多个wheres),然后可以在构建阶段结束时“呈现”这种情况。

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

An OR-Mapper, such as Microsoft's LINQ OR-Mapper,例如Microsoft的LINQ

Here are some examples: 这里有些例子:

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;

Some links to get you started: 一些使您入门的链接:

See the above, and I've seen more than one programmer head down this road. 看到上面的内容,我已经看到了不止一个程序员走这条路。 (And I've told more than one programmer that I've seen more than one programmer ..., but usually they end up finding out on their own how well it works.) (而且我已经告诉了不止一位程序员,我见过不止一位程序员...,但是通常他们最终只能自己找出其工作原理。)

The difficulty I see is that you are adding substantial complexity without offering much in the way of abstraction. 我看到的困难是,您在没有提供太多抽象方法的情况下增加了相当大的复杂性。 You pretty much need to know what SQL you'll be ending up with anyway. 您几乎需要知道您最终将使用哪种SQL。

(At least to the degree that the pattern is as represented in your illustration, where you're specifying the clauses directly. ORMs abstract well beyond that.) (至少在某种程度上,该模式如您在插图中所表示的那样,您可以直接在其中指定子句。ORM远远超出了该抽象。)

The python package SQLAlchemy has an ORM layer, but it also has an SQL generation layer. python包SQLAlchemy具有ORM层,但也具有SQL生成层。

[I realise you tagged this post c# and .net, but I thought you might like to see what else is out there] [我意识到您已将此帖子标记为c#和.net,但我想您可能想看看那里还有什么]

Here is some example code: 这是一些示例代码:

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.

Typically, you would execute the statement by using SQLAlchemy to connect to a database. 通常,您将通过使用SQLAlchemy连接数据库来执行语句。 Then you can do: 然后,您可以执行以下操作:

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

Hope this helps. 希望这可以帮助。

You can try MetaDb . 您可以尝试使用MetaDb There is some work done. 已经完成了一些工作。 Sample query http://i3.codeplex.com/Project/Download/FileDownload.aspx?ProjectName=metadb&DownloadId=11482 示例查询http://i3.codeplex.com/Project/Download/FileDownload.aspx?ProjectName=metadb&DownloadId=11482

But if you can use .NET 3.5, you can use LINQ. 但是,如果可以使用.NET 3.5,则可以使用LINQ。

在.Net中,Linq几乎完成了您正在谈论的内容。

If you're still using .NET 2.0 and haven't moved onwards to LINQ, then I would create a base statement class, then create classes which allow for a decorator pattern. 如果您仍在使用.NET 2.0,但尚未开始使用LINQ,那么我将创建一个基本语句类,然后创建允许装饰器模式的类。

That way you can just keep adding what you need to your base statement. 这样,您就可以继续在基本语句中添加所需的内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM