适用于 .NET 的后关系数据库入门:Matisse - 第 4 部分






4.86/5 (26投票s)
2004年3月15日
4分钟阅读

167678
使用后关系数据库进行 ADO.NET 编程
引言
这是关于适用于 .NET 的 Matisse 后关系数据库的入门系列文章的第四篇。之前的文章列表如下:
第 4 部分涵盖 ADO.NET 编程。文章从一个简单的示例开始,然后说明如何使用 SQL REF()
函数检索 .NET 对象而不是值,这是使用 Matisse 的优势之一。本文还展示了一个使用 DataGrid
与后关系数据库的简单 GUI 应用程序。
如果您已经熟悉 ADO.NET,那么本文中除了如何使用 SQL REF()
函数直接检索对象而无需任何映射之外,并没有什么真正新的内容。这在下面的“返回对象”部分有解释。
简单示例
为了在本文中描述 ADO.NET 编程,我使用了与前几篇文章相同的模式。
下一个程序将连接到 Matisse 数据库,执行一个 SQL SELECT
语句,然后检索返回的值。
using System;
using System.Data;
using com.matisse;
using com.matisse.Data;namespace ConsoleApplication1
{
class ConsoleAppClass1
{
[STAThread]
static void Main(string[] args)
{
// Create a connection object using a connection string
MtDatabase myConn = new MtDatabase(
"Server=localhost;Database=example");
myConn.Open();
// Create an instance of MtCommand
IDbCommand myCmd = myConn.CreateCommand();
myCmd.CommandText = "SELECT ProjectName, Budget FROM Project;";
// Execute the SELECT statement.
// A read-only transaction started by Matisse
IDataReader reader = myCmd.ExecuteReader();
// Read rows
while ( reader.Read() )
{
// Get value for the first and second columns
string pname = reader.GetString(0);
decimal budget = reader.GetDecimal(1);
Console.WriteLine(pname + ", " + budget);
}
// Clean up
reader.Close();
myCmd.Dispose();
myConn.Close();
}
}
}
以下是关于此程序的一些说明:
Matisse 的 ADO.NET 连接对象由 MtDatabase
类创建,该类的名称与标准的命名约定略有不同。
MtDatabase
类和其他 ADO.NET 相关类定义在 com.matisse
和 com.matisse.Data
命名空间中。
返回对象
上面的程序是最基本的 ADO.NET 示例,您随处可见。尽管它证明了 Matisse 就像关系型产品一样工作,但这对我来说并不是那么令人兴奋。Matisse 一个非常有趣的功能是您可以在 ADO.NET 中检索对象而不进行映射。下一段代码展示了如何做到这一点。
// Create a connection object using a connection string
MtDatabase myConn =
new MtDatabase("localhost", "example",
new MtPackageObjectFactory("MatisseApp,PersistentClasses"));
myConn.Open();
// Create an instance of MtCommand
IDbCommand myCmd = myConn.CreateCommand();
myCmd.CommandText =
"SELECT REF(p) FROM Project p WHERE p.Budget >= 10000;"; // -- A
// Execute the SELECT statement.
MtDataReader reader = (MtDataReader) myCmd.ExecuteReader();
while ( reader.Read() )
{
// Get the Project object from the ADO.NET Reader object
Project prj = (Project) reader.GetObject(0); // -- B
// Get the manager of the project.
// This is a navigation through relationship.
Manager mgr = prj.ManagedBy; // -- C
// Get the members of the project
Employee[] members = prj.Members; // -- D
foreach (Employee emp in members)
{
...
}
}
首先,您需要使用代码生成工具(在本系列第 3 部分中有介绍)从数据库模式生成 Project
类,以便直接检索对象。
如上所示,要使用 SQL SELECT
语句检索对象,请在 select
子句(A 行)中使用 REF
函数,并在 ADO.NET DataReader
对象上调用 GetObject
方法(B 行)。
获取 Project
对象后,您可以通过访问 Project
对象的属性来获取项目的经理(C 行)和项目中工作的成员(D 行)。这是使用后关系数据库的另一个优点。它真正简化了数据访问层。
请注意,您需要将 MtPackageObjectFactory
对象传递给 MtDatabase
构造函数,以指定存根类(例如 Manager
)的位置,即位于名为 PersistentClasses
的程序集中 MatisseApp
命名空间中。
DataGrid 示例
下一段代码摘自一个使用 DataGrid
显示 SQL 查询结果的程序(参见下图)。同样,这段代码没有什么特别之处,但它证明了 Matisse 提供了一个关系型接口。
private void button1_Click(object sender, System.EventArgs e)
{
MtDatabase myConn = new MtDatabase("localhost", "example");
myConn.Open();
// Create a DataAdapter
MtDataAdapter myCommand =
new MtDataAdapter(
"SELECT ProjectName, Budget, ManagedBy.Name Manager
FROM Project;", myConn);
DataSet ds = new DataSet();
myCommand.Fill(ds, "Projects");
dataGrid1.SetDataBinding(ds, "Projects");
myConn.Close();
}
调用 SQL 存储方法
您可以使用“StoredProcedure
”类型的 ADO.NET 命令对象调用 Matisse SQL 存储方法。或者,您可以使用 CALL 语法调用静态存储方法。例如,假设您定义了下一个存储方法,该方法根据姓名查找 Employee
对象:
CREATE STATIC METHOD FindByName(nameToFind VARCHAR)
RETURNS Employee
FOR Employee
BEGIN
DECLARE emp Employee;
SELECT REF(e) INTO emp FROM Employee e
WHERE Name = nameToFind;
RETURN emp;
END;
由于上述方法返回单个对象,您可以使用 ExecuteScalar
方法来执行存储方法。
// Create a command object from a connection object
MtCommand mtcmd = myConn.CreateCommand();
// Set the CALL statement to call the stored method
mtcmd.CommandText = "CALL Employee::FindByName('Ken Jupiter');";
// Execute the stored method, and get the returned object
Employee emp = (Employee) mtcmd.ExecuteScalar();
Matisse 还有一个有趣的功能,允许您像调用常规 .NET 方法一样调用对象上的 SQL 存储方法(非静态),无需 SQL 语句。我将在下一篇文章中讨论此功能。
总结和下一篇文章
在本文中,我展示了如何将 ADO.NET 与 Matisse 结合使用,特别是如何使用 ADO.NET 返回对象。
在下一篇文章中,我将讨论在 Matisse 的 .NET 编程中使用“Object APIs”,它提供了性能改进以及使用全文索引的能力。
附录:使用 ADO.NET 插入对象
下一段代码等同于上一篇文章中展示的程序,用于通过“Object APIs”插入 Employee
、Manager
和 Project
对象。
// Create a connection object
MtDatabase myConn =
new MtDatabase("localhost", "example");
myConn.Open();
IDbTransaction dbtran = myConn.BeginTransaction();
// Create an instance of MtCommand
IDbCommand myCmd = myConn.CreateCommand();
// Insert an Empoyee #1
myCmd.CommandText = "INSERT INTO Employee (Name, BirthDate)" +
"VALUES ('John Venus', DATE '1955-10-01') RETURNING INTO emp1";
myCmd.ExecuteNonQuery();
// Insert another Employee #2
myCmd.CommandText = "INSERT INTO Employee (Name, BirthDate)"+
"VALUES ('Amy Mars', DATE '1965-9-25') RETURNING INTO emp2";
myCmd.ExecuteNonQuery();
// Insert a Manager
myCmd.CommandText = "INSERT INTO Manager (Name, BirthDate, Title)"+
"VALUES ('Ken Jupiter', DATE '1952-12-15', 'Director')"+
" RETURNING INTO mgr";
myCmd.ExecuteNonQuery();
// Insert a Project with the above manager
// and two employees as its members
myCmd.CommandText =
"INSERT INTO Project (ProjectName, ManagedBy, Members) "+
"VALUES ('Whidbey', mgr, SELECTION(emp1, emp2))";
myCmd.ExecuteNonQuery();
dbtran.Commit();
myConn.Close();
历史
- 2004 年 4 月 27 日:初始版本
许可证
本文没有明确附加许可,但可能包含文章文本或下载文件本身的使用条款。如有疑问,请通过下方的讨论区与作者联系。您可以在此处找到作者可能使用的许可列表。