不写文章有几日了,这些天都浪迹于java程序中,潜心修炼java中的Spring框架,感触良多。不过我还是不打算写java相关的文章,因为java我还是菜鸟。前些天写过关于自己的一个ORM框架(点击阅读),希望看过的同仁们有些收获。做程序我喜欢开源,虽然上次老赵"鄙视"过我们,不是其他的原因,开源达到了资源共享的目的。.NET 中出的ORM框架也不少了,Hibernate的克隆版NHibernate,还有Linq to SQL ,Entity FrameWork ,ALinq。接下我要分享的就是要ALinq这个没有多少人知道的ORM框架。
一. ALinq 简介
ALinq 是一款与 Linq to SQL 相兼容的 ORM 映射框架。它对Linq to SQL进行了一系列的扩展。Linq to SQL我们都知道它很难兼容除了SQL Server 之外的其他数据库。而ALinq 就大大改善了这种弊端,它支持多种数据库,包括MSSQL2000,20005,Access,SQLite,MySQL,Oracle,与 Friebird 。 到目前我只使用过SQL Server,Mysql数据库作为映射,Mysql还是有些地方做的不是太好个人感觉。SQL Server自然就不用说了,其余的数据库没有试过。感觉ALinq 还是挺不错的。
二.ALinq 安装
ALinq 插件安装文件下载: 点击下载 /Files/qingyuan/ALinq.rar
大家都熟知Linq 的使用,使用环境大家也就应该了解了,ALinq 和Linq一样,所需的环境基本相同。使用VS2008集成开发环境,当然VS2010也可以使用。
1.安装ALinq插件
2.程序中添加ALinq 设计器
3.ALinq 新建工程模型
4.ALinq 模型设计器
三. ALinq 于Linq to SQL 实体模型的比较
ALinq Context 上下文实体对象
Linq to SQL Context上下问实体对象
从上面的代码可以看出,Context 修饰的特性类不同,所继承的父类也不同。ALinq 中使用了ALinq.Mapping.DataBaseAttribute 和ALinq.Mapping.ProviderAttribute 来修饰DataContext上下文。其中第一个特性和Linq to SQL有着类似的功能,但是第二个特性是Linq to SQL所没有的特性,也正是因为这个特性,上面使用了一个sql加载驱动模型,从这里我们可以看出它是使用的那种类型的数据库,这里我们看到的Sql2000Provider有些不准确,这也是SQL Server 映射出现的一个特殊的地方。至于为什么我现在也不明白,毕竟不是开源的,而且是收费的ALinq。 ALinq 在连接数据库的时候,必须指定数据库的连接对象SqlConnection ,而Linq to SQL 只需要指定数据库连接的字符串就可以了。当然我们可以通过扩展方法来实现这个功能,但是ALinq 本身是没有实现的。
ALinq 实体类
ALinq 实体类代码样例
1 [Table(Name="dbo.TabGameContent")]
2 public partial class TabGameContent : INotifyPropertyChanging, INotifyPropertyChanged
3 {
4
5 private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
6
7 private int _Id;
8
9 private string _Title;
10
11 private int _ParentID;
12
13 private int _MenuID;
14
15 private string _NewsContent;
16
17 private System.DateTime _CreateTime;
18
19 private int _NewsIndex;
20
21 private string _Remark;
22
23 private string _Ext1;
24
25 private string _Ext2;
26
27 #region Extensibility Method Definitions
28 partial void OnLoaded();
29 partial void OnValidate(ChangeAction action);
30 partial void OnCreated();
31 partial void OnIdChanging(int value);
32 partial void OnIdChanged();
33 partial void OnTitleChanging(string value);
34 partial void OnTitleChanged();
35 partial void OnParentIDChanging(int value);
36 partial void OnParentIDChanged();
37 partial void OnMenuIDChanging(int value);
38 partial void OnMenuIDChanged();
39 partial void OnNewsContentChanging(string value);
40 partial void OnNewsContentChanged();
41 partial void OnCreateTimeChanging(System.DateTime value);
42 partial void OnCreateTimeChanged();
43 partial void OnNewsIndexChanging(int value);
44 partial void OnNewsIndexChanged();
45 partial void OnRemarkChanging(string value);
46 partial void OnRemarkChanged();
47 partial void OnExt1Changing(string value);
48 partial void OnExt1Changed();
49 partial void OnExt2Changing(string value);
50 partial void OnExt2Changed();
51 #endregion
52
53 public TabGameContent()
54 {
55 OnCreated();
56 }
57
58 [Column(Name="ID", Storage="_Id", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", CanBeNull=false, IsPrimaryKey=true, IsDbGenerated=true, UpdateCheck=UpdateCheck.Never)]
59 public int Id
60 {
61 get
62 {
63 return this._Id;
64 }
65 set
66 {
67 if ((this._Id != value))
68 {
69 this.OnIdChanging(value);
70 this.SendPropertyChanging();
71 this._Id = value;
72 this.SendPropertyChanged("Id");
73 this.OnIdChanged();
74 }
75 }
76 }
77
78 [Column(Storage="_Title", DbType="NVarChar(200) NOT NULL", CanBeNull=false, UpdateCheck=UpdateCheck.Never)]
79 public string Title
80 {
81 get
82 {
83 return this._Title;
84 }
85 set
86 {
87 if ((this._Title != value))
88 {
89 this.OnTitleChanging(value);
90 this.SendPropertyChanging();
91 this._Title = value;
92 this.SendPropertyChanged("Title");
93 this.OnTitleChanged();
94 }
95 }
96 }
97
98 [Column(Storage="_ParentID", DbType="Int NOT NULL", CanBeNull=false, UpdateCheck=UpdateCheck.Never)]
99 public int ParentID
100 {
101 get
102 {
103 return this._ParentID;
104 }
105 set
106 {
107 if ((this._ParentID != value))
108 {
109 this.OnParentIDChanging(value);
110 this.SendPropertyChanging();
111 this._ParentID = value;
112 this.SendPropertyChanged("ParentID");
113 this.OnParentIDChanged();
114 }
115 }
116 }
117
118 [Column(Storage="_MenuID", DbType="Int NOT NULL", CanBeNull=false, UpdateCheck=UpdateCheck.Never)]
119 public int MenuID
120 {
121 get
122 {
123 return this._MenuID;
124 }
125 set
126 {
127 if ((this._MenuID != value))
128 {
129 this.OnMenuIDChanging(value);
130 this.SendPropertyChanging();
131 this._MenuID = value;
132 this.SendPropertyChanged("MenuID");
133 this.OnMenuIDChanged();
134 }
135 }
136 }
137
138 [Column(Storage="_NewsContent", DbType="Text NOT NULL", CanBeNull=false, UpdateCheck=UpdateCheck.Never)]
139 public string NewsContent
140 {
141 get
142 {
143 return this._NewsContent;
144 }
145 set
146 {
147 if ((this._NewsContent != value))
148 {
149 this.OnNewsContentChanging(value);
150 this.SendPropertyChanging();
151 this._NewsContent = value;
152 this.SendPropertyChanged("NewsContent");
153 this.OnNewsContentChanged();
154 }
155 }
156 }
157
158 [Column(Storage="_CreateTime", DbType="DateTime NOT NULL", CanBeNull=false, UpdateCheck=UpdateCheck.Never)]
159 public System.DateTime CreateTime
160 {
161 get
162 {
163 return this._CreateTime;
164 }
165 set
166 {
167 if ((this._CreateTime != value))
168 {
169 this.OnCreateTimeChanging(value);
170 this.SendPropertyChanging();
171 this._CreateTime = value;
172 this.SendPropertyChanged("CreateTime");
173 this.OnCreateTimeChanged();
174 }
175 }
176 }
177
178 [Column(Storage="_NewsIndex", DbType="Int NOT NULL", CanBeNull=false, UpdateCheck=UpdateCheck.Never)]
179 public int NewsIndex
180 {
181 get
182 {
183 return this._NewsIndex;
184 }
185 set
186 {
187 if ((this._NewsIndex != value))
188 {
189 this.OnNewsIndexChanging(value);
190 this.SendPropertyChanging();
191 this._NewsIndex = value;
192 this.SendPropertyChanged("NewsIndex");
193 this.OnNewsIndexChanged();
194 }
195 }
196 }
197
198 [Column(Storage="_Remark", DbType="NVarChar(100)", UpdateCheck=UpdateCheck.Never)]
199 public string Remark
200 {
201 get
202 {
203 return this._Remark;
204 }
205 set
206 {
207 if ((this._Remark != value))
208 {
209 this.OnRemarkChanging(value);
210 this.SendPropertyChanging();
211 this._Remark = value;
212 this.SendPropertyChanged("Remark");
213 this.OnRemarkChanged();
214 }
215 }
216 }
217
218 [Column(Storage="_Ext1", DbType="NVarChar(100)", UpdateCheck=UpdateCheck.Never)]
219 public string Ext1
220 {
221 get
222 {
223 return this._Ext1;
224 }
225 set
226 {
227 if ((this._Ext1 != value))
228 {
229 this.OnExt1Changing(value);
230 this.SendPropertyChanging();
231 this._Ext1 = value;
232 this.SendPropertyChanged("Ext1");
233 this.OnExt1Changed();
234 }
235 }
236 }
237
238 [Column(Storage="_Ext2", DbType="NVarChar(100)", UpdateCheck=UpdateCheck.Never)]
239 public string Ext2
240 {
241 get
242 {
243 return this._Ext2;
244 }
245 set
246 {
247 if ((this._Ext2 != value))
248 {
249 this.OnExt2Changing(value);
250 this.SendPropertyChanging();
251 this._Ext2 = value;
252 this.SendPropertyChanged("Ext2");
253 this.OnExt2Changed();
254 }
255 }
256 }
257
258 public event PropertyChangingEventHandler PropertyChanging;
259
260 public event PropertyChangedEventHandler PropertyChanged;
261
262 protected virtual void SendPropertyChanging()
263 {
264 if ((this.PropertyChanging != null))
265 {
266 this.PropertyChanging(this, emptyChangingEventArgs);
267 }
268 }
269
270 protected virtual void SendPropertyChanged(String propertyName)
271 {
272 if ((this.PropertyChanged != null))
273 {
274 this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
275 }
276 }
277 }
Linq to SQL 实体类
Linq to SQL 实体类代码样例
1 [Serializable]
2 [Table(Name="dbo.TabGameContent")]
3 public partial class TabGameContent : INotifyPropertyChanging, INotifyPropertyChanged
4 {
5
6 private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
7
8 private int _ID;
9
10 private string _Title;
11
12 private int _ParentID;
13
14 private int _MenuID;
15
16 private string _NewsContent;
17
18 private System.DateTime _CreateTime;
19
20 private int _NewsIndex;
21
22 private string _Remark;
23
24 private string _Ext1;
25
26 private string _Ext2;
27
28 #region Extensibility Method Definitions
29 partial void OnLoaded();
30 partial void OnValidate(System.Data.Linq.ChangeAction action);
31 partial void OnCreated();
32 partial void OnIDChanging(int value);
33 partial void OnIDChanged();
34 partial void OnTitleChanging(string value);
35 partial void OnTitleChanged();
36 partial void OnParentIDChanging(int value);
37 partial void OnParentIDChanged();
38 partial void OnMenuIDChanging(int value);
39 partial void OnMenuIDChanged();
40 partial void OnNewsContentChanging(string value);
41 partial void OnNewsContentChanged();
42 partial void OnCreateTimeChanging(System.DateTime value);
43 partial void OnCreateTimeChanged();
44 partial void OnNewsIndexChanging(int value);
45 partial void OnNewsIndexChanged();
46 partial void OnRemarkChanging(string value);
47 partial void OnRemarkChanged();
48 partial void OnExt1Changing(string value);
49 partial void OnExt1Changed();
50 partial void OnExt2Changing(string value);
51 partial void OnExt2Changed();
52 #endregion
53
54 public TabGameContent()
55 {
56 OnCreated();
57 }
58
59 [Column(Storage="_ID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
60 public int ID
61 {
62 get
63 {
64 return this._ID;
65 }
66 set
67 {
68 if ((this._ID != value))
69 {
70 this.OnIDChanging(value);
71 this.SendPropertyChanging();
72 this._ID = value;
73 this.SendPropertyChanged("ID");
74 this.OnIDChanged();
75 }
76 }
77 }
78
79 [Column(Storage="_Title", DbType="NVarChar(200) NOT NULL", CanBeNull=false)]
80 public string Title
81 {
82 get
83 {
84 return this._Title;
85 }
86 set
87 {
88 if ((this._Title != value))
89 {
90 this.OnTitleChanging(value);
91 this.SendPropertyChanging();
92 this._Title = value;
93 this.SendPropertyChanged("Title");
94 this.OnTitleChanged();
95 }
96 }
97 }
98
99 [Column(Storage="_ParentID", DbType="Int NOT NULL")]
100 public int ParentID
101 {
102 get
103 {
104 return this._ParentID;
105 }
106 set
107 {
108 if ((this._ParentID != value))
109 {
110 this.OnParentIDChanging(value);
111 this.SendPropertyChanging();
112 this._ParentID = value;
113 this.SendPropertyChanged("ParentID");
114 this.OnParentIDChanged();
115 }
116 }
117 }
118
119 [Column(Storage="_MenuID", DbType="Int NOT NULL")]
120 public int MenuID
121 {
122 get
123 {
124 return this._MenuID;
125 }
126 set
127 {
128 if ((this._MenuID != value))
129 {
130 this.OnMenuIDChanging(value);
131 this.SendPropertyChanging();
132 this._MenuID = value;
133 this.SendPropertyChanged("MenuID");
134 this.OnMenuIDChanged();
135 }
136 }
137 }
138
139 [Column(Storage="_NewsContent", DbType="Text NOT NULL", CanBeNull=false, UpdateCheck=UpdateCheck.Never)]
140 public string NewsContent
141 {
142 get
143 {
144 return this._NewsContent;
145 }
146 set
147 {
148 if ((this._NewsContent != value))
149 {
150 this.OnNewsContentChanging(value);
151 this.SendPropertyChanging();
152 this._NewsContent = value;
153 this.SendPropertyChanged("NewsContent");
154 this.OnNewsContentChanged();
155 }
156 }
157 }
158
159 [Column(Storage="_CreateTime", DbType="DateTime NOT NULL")]
160 public System.DateTime CreateTime
161 {
162 get
163 {
164 return this._CreateTime;
165 }
166 set
167 {
168 if ((this._CreateTime != value))
169 {
170 this.OnCreateTimeChanging(value);
171 this.SendPropertyChanging();
172 this._CreateTime = value;
173 this.SendPropertyChanged("CreateTime");
174 this.OnCreateTimeChanged();
175 }
176 }
177 }
178
179 [Column(Storage="_NewsIndex", DbType="Int NOT NULL")]
180 public int NewsIndex
181 {
182 get
183 {
184 return this._NewsIndex;
185 }
186 set
187 {
188 if ((this._NewsIndex != value))
189 {
190 this.OnNewsIndexChanging(value);
191 this.SendPropertyChanging();
192 this._NewsIndex = value;
193 this.SendPropertyChanged("NewsIndex");
194 this.OnNewsIndexChanged();
195 }
196 }
197 }
198
199 [Column(Storage="_Remark", DbType="NVarChar(100)")]
200 public string Remark
201 {
202 get
203 {
204 return this._Remark;
205 }
206 set
207 {
208 if ((this._Remark != value))
209 {
210 this.OnRemarkChanging(value);
211 this.SendPropertyChanging();
212 this._Remark = value;
213 this.SendPropertyChanged("Remark");
214 this.OnRemarkChanged();
215 }
216 }
217 }
218
219 [Column(Storage="_Ext1", DbType="NVarChar(100)")]
220 public string Ext1
221 {
222 get
223 {
224 return this._Ext1;
225 }
226 set
227 {
228 if ((this._Ext1 != value))
229 {
230 this.OnExt1Changing(value);
231 this.SendPropertyChanging();
232 this._Ext1 = value;
233 this.SendPropertyChanged("Ext1");
234 this.OnExt1Changed();
235 }
236 }
237 }
238
239 [Column(Storage="_Ext2", DbType="NVarChar(100)")]
240 public string Ext2
241 {
242 get
243 {
244 return this._Ext2;
245 }
246 set
247 {
248 if ((this._Ext2 != value))
249 {
250 this.OnExt2Changing(value);
251 this.SendPropertyChanging();
252 this._Ext2 = value;
253 this.SendPropertyChanged("Ext2");
254 this.OnExt2Changed();
255 }
256 }
257 }
258
259 public event PropertyChangingEventHandler PropertyChanging;
260
261 public event PropertyChangedEventHandler PropertyChanged;
262
263 protected virtual void SendPropertyChanging()
264 {
265 if ((this.PropertyChanging != null))
266 {
267 this.PropertyChanging(this, emptyChangingEventArgs);
268 }
269 }
270
271 protected virtual void SendPropertyChanged(String propertyName)
272 {
273 if ((this.PropertyChanged != null))
274 {
275 this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
276 }
277 }
278 }
其实两者相比较起来没有多少不同,只不过一个命名空间的不同而已。因为他们实现的功能都是完全一样的。属性的定义,以及事件驱动模式修改属性值等等基本都差不多。这里不做过多的讲解,相信使用过Linq 的都能够很好的接受ALinq。
四.ALinq 查询数据库的简单例子
先看看ALinq查询数据的一个简单例子,让我们从整体上了解一下ALinq 的庐山真面目。
ALinq 查询数据库
1 static void Main(string[] args)
2 {
3 string sqlConnection = @"server=PC-201002220938\SQLEXPRESS;database=eBrainWebDb;Integrated Security=true";
4 var context = new DataContext(new SqlConnection(sqlConnection),typeof(ALinq.SqlClient.Sql2005Provider));
5 var linq = from c in context.GetTable<TabGameContent>() where c.MenuID == 2 select c;
6 foreach (var item in linq)
7 {
8 Console.WriteLine(item.Id);
9 }
10 }
我相信大家都一定很惊讶,为什么一模一样。是的,ALinq 都是Linq to SQL 的一个克隆版,有句话是这么说的:"不仅仅是模仿,更是超越"。我们先不管这些,其实仔细的人已经看出了这里还是有一个不同的地方。我们比较一下Linq to sQL 查询的例子。
Linq to SQL 查询数据库例子
1 /// <summary>
2 /// 查询所有的内容
3 /// </summary>
4 /// <returns></returns>
5 public IList<TabGameContent> GetTabGameContentList()
6 {
7 eBrainWebDbDataContext context = new eBrainWebDbDataContext(Conn);
8 return context.TabGameContent.OrderByDescending(c => c.CreateTime).ToList<TabGameContent>();
9 }
这个例子的Conn是连接数据库的字符串。他们两者的不同在于DataContext 传入的参数不同,在SQL Server 数据库中ALinq的DataContext 上下文参数必须是数据库连接对象,并且指定数据库加载驱动类型。Linq to SQL 就不同了,它可以直接指定数据库连接字符串。其实看到这里两者也就并无太大差别了。
(注:更多文章,继续关注)