当前位置: 首页 > 工具软件 > CSLA .NET > 使用案例 >

2_CSLA.Net关于数据库的访问

张永嘉
2023-12-01

 

1_CSLA.Net在Web应用开发中常用类及说明

数据的访问方法有如下方法:

• ADO.NET Connection, Command, DataReader objects

• LINQ to SQL

• ADO.NET Entity Framework

• Remote XML services

• XML data files (or other text files)

大家都知道CSLA的数据访问门户要求提供DataPortal_XYZ方法。

数据访问可以直接把代码放到业务对象类中、分离在单独的类中、分离在单独的程序集中、使用对象工厂方法。

1直接把代码放到业务对象类中:

这种方法直接把代码写在业务对象类中,偶合性很强。

private void DataPortal_Fetch(SingleCriteria<CustomerEdit, int> criteria)

{

using (var ctx = ConnectionManager<SqlConnection>.GetManager("MyDb"))

{

using (var cm = ctx.Connection.CreateCommand())

{

cm.CommandType = CommandTypes.Text;

cm.CommandText = "SELECT Id, Name FROM Customer WHERE id=@id";

using (var dr = new SafeDataReader(cm.ExecuteReader()))

{

dr.Read();

LoadProperty(IdProperty, dr.GetInt32("Id"));

LoadProperty(NameProperty, dr.GetString("Name"));

}

}

}

}

这样的代码清晰直观,性能也是最好的,因为直接使用.net底层的DataReader。同时也可以使用.NET的最新数据访问技术,LINQ to SQL, the ADO.NET Entity Framework

    同时这样的实现是不能达到数据访问的重用,因为代码直接写死在业务类中,没办重用。这种方式就没有数据访问层,只有UI层和业务对象层。

2分离在单独的类中:

分离在单独的类中,相对增加了系统的复杂性,同时也带来其它好处理。分离主要考虑的因素有:

l         可以重用数据库访问层

l         方便从一种数据访问方式转换到另一种访问方式(from LINQ to SQL to the ADO.NET Entity Framework)

l         方便从一种数据库向另一种数据库的转换(From Oracle to SQL Server

 

private void DataPortal_Fetch(SingleCriteria<CustomerEdit, int> criteria)

{

using (var dal = new CustomerDal())

{

using (SafeDataReader dr = dal.GetCustomer(criteria.Value))

{

dr.Read();

LoadProperty(IdProperty, dr.GetInt32("Id"));

LoadProperty(NameProperty, dr.GetString("Name"));

}

}

}

 

3使用对象工厂方法

public class CustomerFactory : ObjectFactory

{

public object Fetch(SingleCriteria<Customer, int> criteria)

{

using (var ctx = ConnectionManager<SqlConnection>.GetManager("MyDb"))

{

using (var cm = ctx.Connection.CreateCommand())

{

cm.CommandType = CommandTypes.Text;

cm.CommandText = "SELECT Id, Name FROM Customer WHERE id=@id";

cm.Parameters.AddWithValue("@id", criteria.Value);

using (var dr = new SafeDataReader(cm.ExecuteReader()))

{

dr.Read();

var result = (BusinessLibrary.CustomerEdit)Activator.CreateInstance(

typeof(BusinessLibrary.CustomerEdit), true);

MarkNew(result);

result.LoadData(dr);

return result;

}

}

}

}

}

public void LoadData(SafeDataReader dr)

{

LoadProperty(IdProperty, dr.GetInt32("Id"));

LoadProperty(NameProperty, dr.GetString("Name"));

}

这种方法会形成循环引用,既DAL类要引用业务对象类,因为要对业务对象类的属性赋值。业务对象类要引用DAL中,因为要使用DAL来访问数据库。我们一般喜欢DAL与具体业务无关,业务对象类要引用DAL,而不是相互引用。

LoadData还有一种形式,就是DAL返回的是强类型的数据

internal void LoadData(Customer data)

{

LoadProperty(IdProperty, data.Id);

LoadProperty(NameProperty, data.Name);

}

我不喜欢这种方式,这样会造成数据二次组装,第一次是从数据库中读出数据构造强类型的CustomerCustomer就一个数据库实体类,一般叫做数据传输类(DTO)。第二次是构造业务对象的属性。我觉得这是种浪费。特别是在返回业务对象集合,要使用二次循环才能得到数据。数据库阶段构造的强类型对我用处不大。

DTO只用于数据传输,是不能与UI进行交互的。这与PetShop中的Model不一样。

 

具体怎么选择要结合具体的系统,主要考虑以下方面

l         性能

l         封装性

l         分层

l         复杂性

 

我选择的是第2种方式,并且DAL返回的类型为SafeDataReader这种方式。因为强类型对我来说用处不大,我们开发时不会把数据访问层由单独的一个人来完成,业务对象由另一个人完成。我想一般的应用这两层都是一个人来完成,所以他对数据库实现和业务实现都清楚,不会搞错字段的名字和用意,在说使用自动化的生成工具,可以减少很多人为错误,特别是数据库字段与业务属性间的对应的关系。这种方式也兼顾了性能的考虑,不要在DAL中做太多与数据访问无关的事。也可以考虑返回DataSet对象,我看CSLA中给的例子都是用SafeDataReader,而DataReader是性能最好的。

    这种方式也保证了业务类、数据访问类各自的封装性。不会因为构造DTO类而重复读写数据。但这种方式与采用DTO类来说,增加了性能,但减少了灵活性。

    对不同的数据库还会有不同的选择,因为目前.NetSQL Server支持的好,又有LINQ TO SQL ADO.NET Entity Framework。如果你只在SQL Serve数据库上开发DAL层就特别方便了,如果采用LINQ TO SQL ADO.NET Entity FrameworkDAL就自动有具有强类型,也不用写SQL语句,灵活性相当大。

    我们主要使用Oracle数据库,所以还是采用DAL返回DataReader的方式。现在也有ADO.NET Entity Framework For Oracle的版本。我对这些东西不太感冒。还是喜欢自己写SQL,自己的控制方法会更灵活。毕竟我们的业务系统会很复杂。

 

 类似资料: