开放源码的对象关系映射工具ORM.NET 查询表 调用存储过程 增加自定义代码

Lookup表

在ORM.NET Object Browser中指定表是lookup表,如下图所示

image

Lookup表明此表的数据是只读的,不会生成任何的新增,删除对象方法(Add[Object], New[Object], or Delete[Object]),列的属性也不包含Set属性。因此,Lookup表是用来表示static的数据,不会发生变化的数据。这样,ORM.NET框架会cache缓存它的值以改善性能。请看下面的代码

// Create a new Lookup object – a sub-classed DataManager
Lookups lookup = new Lookups(Config.Dsn);
// find a specific course and assign a local object reference
Course course = lookup.Courses.FindByClassName("History 101");
// Display some property information about the Course retrieved from the cached Lookup object
Console.WriteLine("Course " + course.ClassName + " " + course.ID);

下面的例子是演示collection的用法,查找创建课程日期大于2002/11/06

// Assign a local Course Collection
CourseCollection courses = lookup.Courses;
// loop through each record in the Course table
foreach(Course c in courses)
  Console.WriteLine("Course Name: " + c.ClassName);
//Create new Course collection with filter applied on the DateCreated property
CourseCollection oldcourses = courses.FilterByDateCreated(DateTime.Parse("11/06/2002"));
 

下面的代码,演示从Lookup中获取数据

Lookups lookups = new Lookups(Config.Dsn);
Schedule s = dm.NewSchedule();  // Create a new Schedule object
// assign the Schedule object to the desired Course object (Parent)
s.Course = lookups.Courses.FindByClassName("History 101"); 
//.. add the rest of the schedule information
dm.CommitAll(); // create the Schedule object with the Parent Course information

Lookup表的另一个作用是用来棒定到ASP.NET DropDownList,请看代码示例,代码简洁

Lookups lookups = new Lookups(Config.Dsn);
// Courses is set as the DataSource - Courses is returned sorted by ID in ascending order.
DropDownListCourses.DataSource = lookups.Courses.SortByID(SortDirection.Ascending);
DropDownListCourses.DataBind();  // bind the data source
 

如果需要更新Lookup的值,比如在单独的维护数据管理程序中,可以调用Lookup.ReRefreshLookups()来刷新cache,重新获取lookup数据。

 

调用存储过程 Working with Stored Procedures

使用ORM.NET的好处之一是,可以通过一套代码,运行在多种数据库平台中(虽然ORM.NET当前只支持SQL Server),所以尽量少用与特定数据库相关的方式,比如存储过程。如果是在系统维护过程中,暂时无法移除对现有的存储过程的依赖,ORM.NET也提供了方法以访问存储过程。

请看下面的SQL Server存储过程定义

ALTER PROC spGetContactDetails
@LastName varchar(50),
@City varchar(50) OUTPUT,
@State varchar(50) OUTPUT
AS
SELECT @City=City, @State=state 
             FROM Teacher t, Contact c 
             WHERE  t.FKContactId=c.Id     AND   LastName=@LastName

ORM.NET框架会自动生成.NET代码封装对它的访问,.NET代码如下

DataManager dm = new DataManager(Config.Dsn);
string CityName = "";              // define and initialize SQL Output params
string StateName = "";
// Pass Input and Output parameters to the Stored procedure
DataSet ds = StoredProcedures.spGetContactDetails("Goldberg",ref CityName, ref StateName);  
Console.WriteLine("Display results: " + CityName + " " + StateName);

针对数据库中的每个存储过程,会生成一个static的方法,放在StoredProcedures类型中。如上代码所示。

这个方法的源代如下所示,虽然只是个简单的封装,却大大简化了客户端调用存储过程的代码。

public static DataSet spGetContactDetails(  System.String LastName, ref System.String City,   
ref System.String State ) { ArrayList arrayParams = new ArrayList(); SqlParameter paramLastName = new SqlParameter( "@LastName", LastName); paramLastName.SqlDbType = (SqlDbType) Enum.Parse( typeof(SqlDbType), "varchar", true); paramLastName.Direction = ParameterDirection.Input; arrayParams.Add( paramLastName ); SqlParameter paramCity = new SqlParameter( "@City", City); paramCity.SqlDbType = (SqlDbType) Enum.Parse( typeof(SqlDbType), "varchar", true); paramCity.Direction = ParameterDirection.Output; arrayParams.Add( paramCity ); SqlParameter paramState = new SqlParameter( "@State", State); paramState.SqlDbType = (SqlDbType) Enum.Parse( typeof(SqlDbType), "varchar", true); paramState.Direction = ParameterDirection.Output; arrayParams.Add( paramState ); DataSet ds = dm.ExecuteProcedure("spGetContactDetails", (SqlParameter[]) arrayParams.ToArray(typeof(SqlParameter))); City = (System.String) paramCity.Value; State = (System.String) paramState.Value; return ds; }

再举例,返回数据集的存储过程,下面的存储过程返回城市和居住在城市里的学生的合计数

CREATE PROC spStudentsByCity
AS
  SELECT City, Count(c.Id) as 'Total'  FROM Student s, Contact c
  WHERE s.FKContactId=c.ID
GROUP BY City

C#.NET调用代码如下所示

DataSet ds1 = StoredProcedures.spStudentsByCity();
foreach (DataRow dr in ds1.Tables[0].Rows)
       Console.WriteLine ("City: " + dr["City"] + " Total: " + dr["Total"]);

如果存储过程返回多个数据集,如下的代码所示

ALTER Proc spStudentContact  @LastName varchar(50)
AS
DECLARE @ContactId int
DECLARE @FKContactId int
SELECT * FROM Student WHERE LastName=@LastName
SELECT @FKContactId=FKContactID FROM Student WHERE LastName=@LastName
SELECT * FROM Contact WHERE ID=@FKContactId

ORM.NET提供了额外的方法PopulateObjectsFromDataSet来展开得到的数据

DataSet ds = StoredProcedures.spStudentContact("Johnson");  // call the stored procedure
String[] arrTables = {"Student","Contact"};   // create the array with the tables included in the DataSet
dm.PopulateObjectsFromDataSet(ds,arrTables);
StudentCollection students = dm.GetStudentCollectionFromDataSet(); 
ContactCollection contacts = dm.GetContactCollectionFromDataSet();
// Work with the objects
foreach(Contact c1 in contacts)
Console.WriteLine("Address: " + c1.Address1);

从代码可以看出,方法PopulateObjectsFromDataSet把查询到的数据集填充到指定的collection中。

 

子类化,增加自定义代码 Sub-classing and extending Generated Class files

ORM.NET考虑到了应用程序开发中,会修改它生成的类型定义。请看代码

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
namespace SampleAppBiz
{
       /// <summary>
       /// Wraps a row and it's columns/children/parents
       /// This class should be customized.
      /// </summary>
       public class Student : StudentTemplate
       {
              /// <summary>
              /// Constructor must have a row and data context.
              /// </summary>
          internal Student( DataManager dataContext, DataRow ROW) : base( dataContext, ROW)
          {
                     row = ROW;
          }
       }
}

在生成的项目代码中,添加方法

public string FullName()
{
    return (this.FirstName + " " + this.LastName);
} 

更合适的,应该是添加为属性

public override string LastName
           {
                 get
                 {
                       return (base.LastName.ToLower());
                 }
                 set
                 {
                       // ensure that the LastName is always set to 
                       // lower-case
                       base.LastName = value.ToLower();
                 }    
}

如果数据库脚本或是关系发生变化,需要重新代码实体定义,这些代码也不会丢失。

posted @ 2011-09-16 15:07  信息化建设  阅读(748)  评论(0编辑  收藏  举报