Javen-Studio 咖啡小屋

http://javenstudio.org - C++ Java 分布式 搜索引擎
Naven's Research Laboratory - Thinking of Life, Imagination of Future

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  24 随笔 :: 57 文章 :: 170 评论 :: 4 Trackbacks

6           SQL集成(SQL Integration

.NET 语言级集成查询可以用来直接查询关系型的数据存储(relational data stores),而不用离开本地编程语言(local programming language)的语法或编译时环境(the syntax or compile-time environment)。这个技巧(This facility),代码名叫 DLinqcode-named DLinq),把 SQL schema 信息的集成(the integration of SQL schema information)的优势带入了(takes advantage of CLR 元数据(metadata)。这个集成(integration)把 SQL 表(table)和视图(view)的定义编译进 CLR 类型,这样能够从任何语言上访问。

 

DLinq 定义了两个核心的属性(two core attributes),[Table] [Column],它们指出(indicate)了哪个 CLR 类型和属性(which CLR types and properties)是符合(correspond to)外部的 SQL 数据(external SQL data)。[Table] 属性能被应用于(applied to)一个类并联合(associates CLR 类型和一个指定的(named SQL 表或视图。这两个属性都是参数化的(parameterized),以允许 SQL 型的元数据(SQL-specific metadata)得以保留(retained)。举例来说,考察下面这段 SQL schema 的定义:

 

create table People (
    Name nvarchar(
32primary key not null
    Age 
int not null
    CanCode bit not 
null
)

create table Orders (
    OrderID nvarchar(
32primary key not null
    Customer nvarchar(
32) not null
    Amount 
int
)

 

与之对等(equivalent)的 CLR 定义看起来如下:

 

[Table(Name="People")]
public class Person {
  [Column(DbType
="nvarchar(32) not null", Id=true)]
  
public string Name; 

  [Column]
  
public int Age;

  [Column]
  
public bool CanCode;
}


[Table(Name
="Orders")]
public class Order {
  [Column(DbType
="nvarchar(32) not null", Id=true)]
  
public string OrderID; 

  [Column(DbType
="nvarchar(32) not null")]        
  
public string Customer; 

  [Column]
  
public int? Amount; 
}

 

通过这个例子注意到,允许为 null nullable)的 column 映射到(map toCLR 里的允许为 null 的类型(允许为 null 的类型首次出现在 .NET Framework version 2),对 SQL 类型来说没有一个与之一一对应的(a 1:1 correspondence withCLR 类型(比如nvarchar, char, text),原始的 SQL 类型在 CLR metadata 里被保留。

 

为发行一个查询而不是一个关系型存储(issue a query against a relational store),LINQ 模式的 Dlinq 实现把查询从它的表达树(expression tree)转换并编成(translates …form into)一个 SQL 表达试和适合远程赋值(suitable for remote evaluation)的 ADO.NET DbCommand 对象。例于考察如下简单的查询:

 

// establish a query context over ADO.NET sql connection
DataContext context = new DataContext(
     
"Initial Catalog=petdb;Integrated Security=sspi");

// grab variables that represent the remote tables that 
// correspond to the Person and Order CLR types
Table<Person> custs = context.GetTable<Person>();
Table
<Order> orders   = context.GetTable<Order>();

// build the query
var query = from c in custs, o in orders
            where o.Customer 
== c.Name
            select 
new 
                       c.Name, 
                       o.OrderID,
                       o.Amount,
                       c.Age
            }


// execute the query
foreach (var item in query) 
    Console.WriteLine(
"{0} {1} {2} {3}"
                      item.Name, item.OrderID, 
                      item.Amount, item.Age);

 

DataContext 类型提供了一个轻量级的转换器(lightweight translator),它的工作是把标准查询操作符(standard query operators)转换成 SQLDataContext 使用现有的 ADO.NET IdbConnection 来访问存储(accessing the store),能够使用一个确定(established)的ADO.NET 连接对象或者一个可以用来创建一个连接的连接字符串(a connection string)的任一个来初始化(initialized)。

 

GetTable 方法提供 IEnumerable 兼容的变量(IEnumerable-compatible variables),能够被用在查询表达式(query expressions)里来代表(represent)远程的表或视图(the remote table or view)。调用 GetTable 不会导致任何与数据库的交互(interaction),更准确的说(rather)它们扮演(representthe potential 通过时用查询表达式来与远程的表或视图相配合(interact with)。在我们上面的例子中,查询不会对存储(store)发送传输的影响(get transmitted to),直到程序迭代出(iterates over)查询表达式为止,在 C# 中使用 foreach 语句也是如此(in this case)。当程序开始迭代完成(iterates over)查询时,DataContext 机构(machinery)把查询表达式树(expression tree)转换成要发送给存储(sent to the store)的如下所示的 SQL 语句:

 

SELECT [t0].[Age], [t1].[Amount], 
       [t0].[Name], [t1].[OrderID]
FROM [Customers] AS [t0], [Orders] AS [t1]
WHERE [t1].[Customer] 
= [t0].[Name]

 

需要重点注意的是通过在本地编程语言(local programming language)中直接(directly)内建查询能力(building query capability),开发人员可以获得关系模型(the relational model)的完全能力(full power),而不用不得不静态地(statically)将关联烘烤进(bake the relationships intoCLR 类型中。成熟的 O/R 映射(Full-blown object/relational mapping)技术还能够为那些希望它泛函性(functionality)的用户利用(take advantage of)这个核心查询能力(core query capability)。

 

 

 

 

 

待续, 错误难免,请批评指正,译者Naven 2005-10-24

posted on 2005-10-30 19:50 Javen-Studio 阅读(561) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理