过去我是使用J2EE开发的,并且对OOD很狂热,几个月前开始使用.NET。现在我知道了在.NET下实现数据持久途径,在操作一个表中多个记录的时候,我认为ADO.net中的DataSets、DataReaders、DataAdapters是非常强大的,但我现在在设计中仍然使用Business Objects ,所以我写了一个小型基于.NET的持久层框架。
在过去使用JDO的时候,我会考虑为每个BO创建映射到数据中表的一个XML格式描述,但是我想到一个更好的方法,那就是使用.NET中的Attributes。我以前在网上看到一篇介绍如何使用attributes的文章使我有了这个打算。
User BO:

User BO
1 public class User
2 {
3 public User(){}
4 private long _id;
5 private string _name;
6 private string _username;
7 private string _password;
8
9 //for each of these fields we have a Property
10 public long UserID {
11 set{_id = value;}
12 get {return _id;}
13 }
14
15 //etc
16 …
17 }
现在把它映射到数据库中:

User
1 [DBTable("Users","dbo")]
2 [Serializable]
3 public class User
4 {
5 public User(){}
6 private long _id;
7 private string _name;
8 private string _username;
9 private string _password;
10
11 [DBPrimaryKeyField("ID_User",DbType.Int16)]
12 [DBColumn("ID_User",DbType.Int16,false)]
13 public long UserID
14 {
15 set{_id = value;}
16 get {return _id;}
17 }
18
19 [DBColumn("Name",DbType.String,true)]
20 public string Name
21 {
22 //set, get
23 }
24
25 [DBColumn("Username",DbType.String,false)]
26 public string Username
27 {
28 //set, get
29 }
30
31 [DBColumn("Password",DbType.String,false)]
32 public string Password
33 {
34 //set, get
35 }
36 }
37
有3个特性类DBTable, DBPrimaryKey, DBColumn.。下面看看它们各自的功能。
DBTable(string tableName, string databaseOwner)
建立BO到数据表的映射
DBPrimaryKey(string pkFieldName, DBType pkFieldType, bool isAutoIncrement)
建立表中主键到BO属性的映射
DBColumn(string tableFieldName, DBType fieldType, bool allowsNulls)
建立表中字段到BO属性的映射
现在来看一下BO的功能。这里用到一个接口IPersistenceService 。

interface IPersistenceService
public interface IPersistenceService
{
object Create(Object o, Type objectType);
void Update(Object o, Type objectType);
void Delete(Object id, Type objectType);
int Count(string condition, Type objectType);
Object GetObject(Object id, Type objectType);
void LoadDataSet(DataSet dataSet, String sqlQuery);
void LoadDataSet(DataSet dataSet, String sqlQuery, String tableName);
object Create(SqlConnection con, Object o, Type objectType);
void Update(SqlConnection con,Object o, Type objectType);
void Delete(SqlConnection con,Object id, Type objectType);
int Count(SqlConnection con,string condition, Type objectType);
Object GetObject(SqlConnection con,Object id, Type objectType);
void LoadDataSet(SqlConnection con,DataSet dataSet, String sqlQuery);
void LoadDataSet(SqlConnection con,DataSet dataSet, String sqlQuery,
String tableName);
SqlConnection GetConnection();
void CloseConnection(SqlConnection con);
}
我们拥有一个取得实现这个接口的工厂。在这个例子中,有一个依赖说SQL Server 的实现PersistenceServiceImpl。我们来看一下这个实现:
String connectionString = “…”;
IPersistenceService ps = PersistenceServiceFactory
现在来创建一个User并且将其持久化。
User u = new User();
u.Name = "Dan Bunea";
u.Password = "myusername";
u.Password = "mypassword";
//obtain id for the new user in the
long id = (long)ps.Create(u,typeof(User));
或者仅需要这样:(如果你不需要获得对象的ID)
ps.Create(u,typeof(User));
现在Users表里有了一个用户,把它取出来。
User U2 = (User)ps.GetObject(id,typeof(User));
更新并且保存。
U2.Name = "Dan Bunea Updates";
U2.Password = "newusername";
U2.Password = "newpassword";
P2s.Update(U2,typeof(User));
是不是很简单?现在来把它删除。
Ps.Delete(id,typeof(User));
如果你有多个操作都使用相同的连接时,我也加入了一些可以很容易的加载DataSet对象的方法。我来说一下要使这些操作都用一个相同连接的方法:

Same Connection
SqlConnection con = ps.GetConnection();
User u = new User();
u.Name = "Dan Bunea";
u.Password = "myusername";
u.Password = "mypassword";
object id = (long)ps.Create(con,u,typeof(User));
User U2 = (User)ps.GetObject(con,id,typeof(User));
U2.Name = "Dan Bunea Updates";
U2.Password = "newusername";
U2.Password = "newpassword";
P2s.Update(con,U2,typeof(User));
Ps.Delete(con,id,typeof(User));
ps.CloseConnection(con);
说一下性能的问题。用户不需要要关心每个BO有关INSERT, UPDATE, DELETE 和 SELECT(使用主键)的操作,使用对象中指定的特性自动生成这些操作的代码。每个对象的每段代码只需要生成一次,可以使用它们对应的参数来调用。下一次执行相同的操作时,就可以从缓存中获取查询对象,使用反射给每个参数赋值,然后再执行。
特别感谢:.....
原文地址:http://www.codeproject.com/dotnet/persistence_by_reflection.asp
第一次翻译,不好的地方请见谅。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架