【Oyster轻量框架】C# ORM 较灵活的轻量数据模型

ORM 这个概念真的是我们开发人员的福音,避免了大量的重复劳动。

而且做些适当的性能调整策略,效率是没有很多影响的,甚至比纯SQL的执行效率更高

,因为我们的应用通常都是给大量用户使用的,这样纯SQL的反而会造成某些瓶颈(具体就不说了,你懂的)。

而现在流行的一些ORM框架的模型要么就是类似 Hibernate 的大量配置,要么就是大量使用 Attribute 的反射生成的。

我参考了两类做了些调整,其实更类似Hibernate 的一个轻量级的框架,好的作品那么就值得以你自己的名字命名!他就叫Oyster!

下面我首先分享一下我的数据模型的处理机制。

C#:

 

View Code
1 /// <summary>
2 /// Code By Tool 2011/3/1 20:23:32
3 /// This is a Entity class
4 ///
5 /// </summary>
6   [Serializable]
7 public class AcHelp : Oyster.OrmEngine.IDataModel
8 {
9 public Type GetDataModelType()
10 {
11 return typeof(AcHelp);
12 }
13
14 #region public - Property
15 public System.Int32? HelpId { get; set; }
16 public System.String Title { get; set; }
17 public System.Object HelpContent { get; set; }
18 public System.String Titletag { get; set; }
19 public System.String Categorytag { get; set; }
20 public System.Int32? SortNum { get; set; }
21 public System.Int32? Status { get; set; }
22 public System.DateTime? CreateTime { get; set; }
23 public System.DateTime? LastChange { get; set; }
24 public System.Int32? CreateUser { get; set; }
25 public System.Int32? LastChangeUser { get; set; }
26 public System.Int32? SortTag { get; set; }
27 public System.Int32? HelpType { get; set; }
28 #endregion
29
30 #region FieldsInfo
31 public const string _HelpId = "HelpId";
32 public const string _Title = "Title";
33 public const string _HelpContent = "HelpContent";
34 public const string _Titletag = "Titletag";
35 public const string _Categorytag = "Categorytag";
36 public const string _SortNum = "SortNum";
37 public const string _Status = "Status";
38 public const string _CreateTime = "CreateTime";
39 public const string _LastChange = "LastChange";
40 public const string _CreateUser = "CreateUser";
41 public const string _LastChangeUser = "LastChangeUser";
42 public const string _SortTag = "SortTag";
43 public const string _HelpType = "HelpType";
44 #endregion
45 }

 

他的配置文件XML:

 

View Code
1 <?xml version="1.0" encoding="utf-8" ?>
2  <Class Name="Model.AcHelp,Model" QueryType="Table" TableName="AC_HELP">
3 <Query>
4 <![CDATA[
5 SELECT
6 HELP_ID
7 ,TITLE
8 ,HELP_CONTENT
9 ,TITLETAG
10 ,CATEGORYTAG
11 ,SORT_NUM
12 ,STATUS
13 ,CREATE_TIME
14 ,LAST_CHANGE
15 ,CREATE_USER
16 ,LAST_CHANGE_USER
17 ,SORT_TAG
18 ,HELP_TYPE
19 FROM AC_HELP
20 WHERE
21 #OysterVal:Condition# #OysterVal:OrderBy#
22  ]]>
23 </Query>
24 <Properties>
25 <Propertie Name="HelpId" ColumnName="HELP_ID" IsUnique="true"/>
26 <Propertie Name="Title" ColumnName="TITLE"/>
27 <Propertie Name="HelpContent" ColumnName="HELP_CONTENT"/>
28 <Propertie Name="Titletag" ColumnName="TITLETAG"/>
29 <Propertie Name="Categorytag" ColumnName="CATEGORYTAG"/>
30 <Propertie Name="SortNum" ColumnName="SORT_NUM"/>
31 <Propertie Name="Status" ColumnName="STATUS"/>
32 <Propertie Name="CreateTime" ColumnName="CREATE_TIME"/>
33 <Propertie Name="LastChange" ColumnName="LAST_CHANGE"/>
34 <Propertie Name="CreateUser" ColumnName="CREATE_USER"/>
35 <Propertie Name="LastChangeUser" ColumnName="LAST_CHANGE_USER"/>
36 <Propertie Name="SortTag" ColumnName="SORT_TAG"/>
37 <Propertie Name="HelpType" ColumnName="HELP_TYPE"/>
38 </Properties>
39  </Class>

 

,这里其实就是对模型和数据表列做了对应,优化的部分就是加了Query语句的配置,因为Select 在系统中是非常重要的,

通常是需要对其做些优化,比如指定索引等,所以提出来作为配置。

然后就是在框架里使用时初始化配置的方法了,比较简单,其实我想说的是其实配置并不是很麻烦的事情。

 

View Code
1 using System;
2  using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.IO;
6 using System.Xml;
7 using Oyster.Enums;
8
9 namespace Oyster.OrmEngine
10 {
11 public class ConfigEnginer
12 {
13 private static ConfigEnginer _instance;
14 /// <summary>
15 /// 配置信息操作引擎
16 /// </summary>
17 public static ConfigEnginer Instance
18 {
19 get
20 {
21 if (_instance == null)
22 {
23 _instance = new ConfigEnginer();
24 }
25 return _instance;
26 }
27 }
28 #region 属性
29 private DataModelCollection _dataModels;
30 public DataModelCollection DataModels
31 {
32 get
33 {
34 if (_dataModels == null)
35 {
36 _dataModels = InitAllQuerySettings();
37 }
38 return _dataModels;
39 }
40 }
41
42 #endregion
43
44 #region 方法
45
46 public DataModelCollection InitAllQuerySettings()
47 {
48 DataModelCollection dics = new DataModelCollection();
49 string path = System.AppDomain.CurrentDomain.BaseDirectory + "/OysterConfig/CLassList.xml";
50 string pathdir = System.AppDomain.CurrentDomain.BaseDirectory;
51 if (!File.Exists(path))
52 {
53 path = System.AppDomain.CurrentDomain.BaseDirectory + "/bin/OysterConfig/CLassList.xml";
54 pathdir = System.AppDomain.CurrentDomain.BaseDirectory + "/bin";
55 }
56 if (File.Exists(path))
57 {
58 XmlDocument xdoc = new XmlDocument();
59 var s = File.ReadAllText(path);
60 xdoc.LoadXml(s);
61
62 var nodes = xdoc.GetElementsByTagName("Class");
63 if (nodes != null)
64 {
65 foreach (XmlNode node in nodes)
66 {
67 string name = node.Attributes["Name"].Value;
68 string classpath = node.Attributes["Path"].Value;
69 if (!File.Exists(classpath))
70 {
71 classpath = pathdir + "/OysterConfig/" + classpath;
72 }
73 if (File.Exists(classpath))
74 {
75 QuerySetting qs = InitQuerySetting(File.ReadAllText(classpath));
76 dics[qs.ClassType as Type] = qs;
77 }
78 }
79 }
80 }
81
82 return dics;
83 }
84
85 public QuerySetting InitQuerySetting(string xml)
86 {
87 QuerySetting setting = null;
88 XmlDocument xdoc = new XmlDocument();
89 xdoc.LoadXml(xml);
90 var classnode = xdoc.SelectSingleNode("Class");
91 if (classnode != null)
92 {
93 string name = classnode.Attributes["Name"].Value;
94 Type t = Type.GetType(name);
95 if (t != null)
96 {
97 setting = new QuerySetting(t);
98 setting.ClassName = t.FullName;
99 setting.ClassType = t;
100 }
101 string querytype = classnode.Attributes["QueryType"].Value;
102 switch (querytype)
103 {
104 case "Table":
105 setting.QueryType = QueryType.Table;
106 string tablename = classnode.Attributes["TableName"].Value;
107 setting.TableName = tablename;
108 break;
109 case "Query":
110 default:
111 setting.QueryType = QueryType.Query;
112 break;
113 }
114 var query = classnode.SelectSingleNode("Query");
115 if (query != null)
116 {
117 setting.QueryString = query.InnerText;
118 }
119 XmlNodeList properties = classnode.SelectNodes("Properties/Propertie");
120 var props = (setting.ClassType as Type).GetProperties();
121 var dicpps = props.ToDictionary((pi) => { return pi.Name; });
122 foreach (XmlNode p in properties)
123 {
124 ColumnSetting colsetting = new ColumnSetting();
125 string pname = p.Attributes["Name"].Value;
126 string pcolname = p.Attributes["ColumnName"].Value;
127 if (p.Attributes["IsUnique"] != null && p.Attributes["IsUnique"].Value.Equals("true"))
128 {
129 colsetting.IsUnique = true;
130 setting.UniqueColumn = colsetting;
131 }
132 colsetting.ColumnName = pcolname;
133 colsetting.Property = pname;
134 if (dicpps.ContainsKey(colsetting.Property))
135 {
136 colsetting.PropertyHandel = dicpps[colsetting.Property];
137 colsetting.PropertyType = colsetting.PropertyHandel.PropertyType;
138 }
139 if (!setting.Columns.ContainsKey(pname))
140 {
141 setting.Columns.Add(pname, colsetting);
142 }
143 }
144 }
145 if (setting.UniqueColumn == null)
146 {
147 throw new Exception("plase set model xml on Propertie IsUnique=\"true\". ");
148 }
149
150 return setting;
151 }
152
153 #endregion
154 }
155 }

这样我就是通过

QuerySetting qs = ConfigEnginer.Instance.DataModels[model_type];

快速获得数据模型的配置啦,这个配置里面还记录了每个类每个属性的 PropertyInfo PropertyHandel;

这个对之后的数据绑定非常方便性能也非常好!~谢谢大家啦

posted on 2011-04-16 01:45  oyster.oy  阅读(2340)  评论(9编辑  收藏  举报

导航