1. 程式人生 > 其它 >ORM對映框架總結--SQL 語句生成元件

ORM對映框架總結--SQL 語句生成元件

轉 https://www.cnblogs.com/qingyuan/archive/2010/04/16/1713658.html

1.SQL語句生成組建

之前說過ORM框架中有一個非常重要的元件,那就是SQL語句生成元件。SQL語句生成元件,顧名思義就是用於生成sql語句的一個元件。之前的Attribute是用於修飾實體資訊,而上一章講的實體分析器分析了實體資訊,在很大一部分程度上,以上做工作就是為這個SQL語句生成元件服務的。

該元件的核心介面是IDbFactory,它實現了介面IDisposable

目前該ORM支援SQL Server資料庫的sql語句生成,在後期過程中會逐步實現對Oracle,Mysql,Access等資料庫的支援

下面是該介面定義的方法圖表:

  1. 2.核心介面

核心介面定義原始碼

1/**
2*2010-2-2
3*
4*情緣
5*
6*IDbFactory介面實現了IDisposable介面,實現該
7*介面的類可以通過IDisposable介面來釋放物件佔用
8*的記憶體。該介面的主要作用適用於根據實體物件來創
9*建SQLServer資料庫指令碼。ORM的主要作用是為了
10*實現物件化操作資料庫,而此操作就是為了實現物件
11*化操作和資料庫語句操作的過渡
12*
13**/
14usingSystem;
15usingSystem.Collections.Generic;
16usingSystem.Linq;
17usingSystem.Text;
18usingCommonData.Entity;
19usingSystem.Data;
20usingCommonData.Model.Core;
21
22namespaceCommonData.Data.Core
23{
24publicinterfaceIDbFactory:IDisposable
25{
26///<summary>
27///根據實體物件公共介面建立插入的sql語句
28///</summary>
29///<paramname="entity">實體公共介面</param>
30///<paramname="param">建立sql語句對應占位符引數</param>
31///<returns></returns>
32stringCreateInsertSql(IEntityentity,outIDataParameter[]param);
33
34///<summary>
35///根據實體型別建立插入sql語句
36///</summary>
37///<paramname="type">實體型別</param>
38///<paramname="value">實體物件</param>
39///<paramname="param">建立sql語句對應占位符引數</param>
40///<returns></returns>
41stringCreateInsertSql(Typetype,objectvalue,outIDataParameter[]param);
42
43///<summary>
44///根據泛型型別建立插入sql語句
45///</summary>
46///<typeparamname="T">泛型型別</typeparam>
47///<paramname="t">泛型實體類</param>
48///<paramname="param">建立sql語句對應占位符引數</param>
49///<returns></returns>
50stringCreateInsertSql<T>(Tt,outIDataParameter[]param)whereT:IEntity;
51
52///<summary>
53///根據實體物件公共介面建立修改的的sql語句
54///該sql語句是根據主鍵列修改的
55///</summary>
56///<paramname="entity">實體公共介面</param>
57///<paramname="param">建立sql語句對應占位符引數</param>
58///<returns></returns>
59stringCreateUpdateSql(IEntityentity,outIDataParameter[]param);
60
61///<summary>
62///根據實體物件型別建立修改的的sql語句
63///</summary>
64///<paramname="type">實體型別</param>
65///<paramname="value">實體物件</param>
66///<paramname="param">建立sql語句對應占位符引數</param>
67///<returns></returns>
68stringCreateUpdateSql(Typetype,objectvalue,outIDataParameter[]param);
69
70///<summary>
71///根據實體物件公共介面建立修改的的sql語句
72///該sql語句是根據一個特定的屬性作為修改條件的
73///</summary>
74///<paramname="entity">實體公共介面</param>
75///<paramname="param">建立sql語句對應占位符引數</param>
76///<paramname="propertyName">屬性名稱</param>
77///<returns></returns>
78stringCreateUpdateSql(IEntityentity,outIDataParameter[]param,stringpropertyName);
79
80///<summary>
81///根據實體物件型別建立修改的的sql語句
82///該sql語句是根據一個特定的屬性作為修改條件的
83///</summary>
84///<paramname="type">實體型別</param>
85///<paramname="value">實體物件</param>
86///<paramname="param">建立sql語句對應占位符引數</param>
87///<paramname="propertyName">屬性名稱</param>
88///<returns></returns>
89stringCreateUpdateSql(Typetype,objectvalue,outIDataParameter[]param,stringpropertyName);
90
91///<summary>
92///根據實體物件公共介面建立修改的的sql語句
93///該sql語句是根據多個特定的屬性作為修改條件的
94///</summary>
95///<paramname="entity">實體公共介面</param>
96///<paramname="param">建立sql語句對應占位符引數</param>
97///<paramname="propertyNames">屬性名稱</param>
98///<returns></returns>
99stringCreateUpdateSql(IEntityentity,outIDataParameter[]param,string[]propertyNames);
100
101///<summary>
102///根據實體物件型別建立修改的的sql語句
103///該sql語句是根據多個特定的屬性作為修改條件的
104///</summary>
105///<paramname="type">實體型別</param>
106///<paramname="value">實體物件</param>
107///<paramname="param">建立sql語句對應占位符引數</param>
108///<paramname="propertyNames">屬性名稱</param>
109///<returns></returns>
110stringCreateUpdateSql(Typetype,objectvalue,outIDataParameter[]param,string[]propertyNames);
111
112///<summary>
113///根據實體物件公共介面建立修改的的sql語句
114///該sql語句是根據查詢組建建立的
115///</summary>
116///<paramname="entity">實體公共介面</param>
117///<paramname="param">建立sql語句對應占位符引數</param>
118///<paramname="component">查詢條件元件</param>
119///<returns></returns>
120stringCreateUpdateSql(IEntityentity,outIDataParameter[]param,ConditionComponentcomponent);
121
122///<summary>
123///根據實體物件公共介面建立刪除sql語句
124///該sql語句是根據實體主鍵刪除
125///</summary>
126///<paramname="entity">實體公共介面</param>
127///<paramname="param">建立sql語句對應占位符引數</param>
128///<returns></returns>
129stringCreateDeleteSql(IEntityentity,outIDataParameter[]param);
130
131///<summary>
132///根據實體物件型別建立刪除sql語句
133///該sql語句是根據實體主鍵刪除
134///</summary>
135///<paramname="type">實體型別</param>
136///<paramname="value">實體物件</param>
137///<paramname="param">建立sql語句對應占位符引數</param>
138///<returns></returns>
139stringCreateDeleteSql(Typetype,objectvalue,outIDataParameter[]param);
140
141///<summary>
142///根據實體物件公共介面的某個屬性建立刪除sql語句
143///該sql語句是根據實體屬性刪除
144///</summary>
145///<paramname="entity">實體公共介面</param>
146///<paramname="param">建立sql語句對應占位符引數</param>
147///<paramname="propertyName">實體屬性名稱</param>
148///<returns></returns>
149stringCreateDeleteSql(IEntityentity,outIDataParameter[]param,stringpropertyName);
150
151///<summary>
152///根據實體物件型別的某個屬性建立刪除sql語句
153///該sql語句是根據實體屬性刪除
154///</summary>
155///<paramname="type">實體型別</param>
156///<paramname="value">實體物件</param>
157///<paramname="param">建立sql語句對應占位符引數</param>
158///<paramname="propertyName">實體屬性名稱</param>
159///<returns></returns>
160stringCreateDeleteSql(Typetype,objectvalue,outIDataParameter[]param,stringpropertyName);
161
162///<summary>
163///根據實體物件公共介面的多個屬性建立刪除sql語句
164///該sql語句是根據實體多個屬性刪除
165///</summary>
166///<paramname="entity">實體公共介面</param>
167///<paramname="param">建立sql語句對應占位符引數</param>
168///<paramname="propertyName">實體屬性名稱陣列</param>
169///<returns></returns>
170stringCreateDeleteSql(IEntityentity,outIDataParameter[]param,string[]propertyNames);
171
172///<summary>
173///根據實體物件型別的多個屬性建立刪除sql語句
174///該sql語句是根據實體多個屬性刪除
175///</summary>
176///<paramname="type">實體了姓</param>
177///<paramname="value">實體物件</param>
178///<paramname="param">建立sql語句對應占位符引數</param>
179///<paramname="propertyNames">實體屬性名稱陣列</param>
180///<returns></returns>
181stringCreateDeleteSql(Typetype,objectvalue,outIDataParameter[]param,string[]propertyNames);
182
183///<summary>
184///根據實體物件公共介面的多個屬性建立刪除sql語句
185///該sql語句使根據查詢組建來建立的
186///</summary>
187///<paramname="entity">實體公共介面</param>
188///<paramname="param">建立sql語句對應占位符引數</param>
189///<paramname="component">實體屬性名稱陣列</param>
190///<returns></returns>
191stringCreateDeleteSql(IEntityentity,outIDataParameter[]param,ConditionComponentcomponent);
192
193///<summary>
194///根據實體的公共介面建立查詢單行資料的sql語句
195///該sql語句是根據資料庫表的主鍵來查詢的
196///</summary>
197///<paramname="entity">實體公共介面</param>
198///<paramname="param">建立sql語句對應占位符引數</param>
199///<returns></returns>
200stringCreateSingleSql(IEntityentity,outIDataParameter[]param);
201
202///<summary>
203///根據實體的公共介面建立查詢單行資料的sql語句
204///該sql語句是根據實體的相應屬性來查詢
205///</summary>
206///<paramname="entity">實體公共介面</param>
207///<paramname="param">建立sql語句對應占位符引數</param>
208///<returns></returns>
209stringCreateSingleSql(IEntityentity,outIDataParameter[]param,string[]propertyNames);
210
211///<summary>
212///根據實體型別建立查詢單行資料的sql語句
213///該sql語句是根據實體的相應屬性來查詢
214///</summary>
215///<paramname="type">實體型別</param>
216///<paramname="value">實體物件</param>
217///<paramname="param">建立sql語句對應占位符引數</param>
218///<paramname="propertyNames">屬性名稱陣列</param>
219///<returns></returns>
220stringCreateSingleSql(Typetype,objectvalue,outIDataParameter[]param,string[]propertyNames);
221
222///<summary>
223///根據實體的型別建立查詢sql語句
224///</summary>
225///<paramname="entityType">實體型別</param>
226///<returns></returns>
227stringCreateSingleSql(TypeentityType);
228
229///<summary>
230///根據實體的型別建立查詢sql語句,
231///該方法指定主鍵值
232///</summary>
233///<paramname="type">實體型別</param>
234///<paramname="pkPropertyValue">主鍵值</param>
235///<paramname="param">建立sql語句對應占位符引數</param>
236///<returns></returns>
237stringCreateSingleSql(Typetype,objectpkPropertyValue,outIDataParameter[]param);
238
239///<summary>
240///根據實體的型別建立查詢該實體物件對應資料庫表的所有資料的sql語句
241///該sql語句用於查詢所有資料,並轉換為相應List<T>集合
242///</summary>
243///<paramname="type">實體的型別</param>
244///<returns></returns>
245stringCreateQuerySql(Typetype);
246
247///<summary>
248///根據實體的某個屬性建立根據該屬性欄位查詢資料的sql語句
249///該sql語句是使用引數中屬性對應欄位作為條件查詢的
250///</summary>
251///<paramname="type">實體型別</param>
252///<paramname="propertyName">屬性名稱</param>
253///<paramname="value">屬性值</param>
254///<paramname="param">sql語句佔位符引數</param>
255///<returns></returns>
256stringCreateQueryByPropertySql(Typetype,stringpropertyName,objectvalue,outIDataParameter[]param);
257
258///<summary>
259///根據實體的某些屬性建立根據該些屬性欄位查詢資料的sql語句
260///該sql語句是使用引數中屬性對應欄位作為條件查詢的,並且該
261///屬性集合都是根據and條件組裝的
262///</summary>
263///<paramname="type">實體型別</param>
264///<paramname="dic">屬性-值集合</param>
265///<paramname="param">sql語句佔位符引數</param>
266///<returns></returns>
267stringCreateQueryByPropertySql(Typetype,IDictionary<string,object>dic,outIDataParameter[]param);
268
269///<summary>
270///根據實體的某些屬性建立根據該些屬性欄位查詢資料的sql語句
271///該sql語句是使用引數中屬性對應欄位作為條件查詢的,並且查
272///詢是根據查詢組建來建立
273///</summary>
274///<paramname="type">實體型別</param>
275///<paramname="dic">屬性-值集合</param>
276///<paramname="param">sql語句佔位符引數</param>
277///<paramname="component">查詢組建</param>
278///<returns></returns>
279stringCreateQueryByPropertySql(Typetype,IDictionary<string,object>dic,outIDataParameter[]param,ConditionComponentcomponent);
280
281///<summary>
282///根據實體型別來建立該實體對應資料庫表的聚合函式查詢sql語句
283///該方法建立的sql語句主要是用於查詢資料行數
284///</summary>
285///<paramname="type">實體型別</param>
286///<paramname="converage">聚合函式列舉型別</param>
287///<returns></returns>
288stringCreateConverageSql(Typetype,Converageconverage);
289
290///<summary>
291///根據實體型別來建立該實體對應資料庫表的聚合函式查詢sql語句
292///該方法建立的sql語句主要是用於統計查詢(最大值,最小值,求和,平均值,資料行數)
293///</summary>
294///<paramname="type">實體型別</param>
295///<paramname="converage">聚合函式列舉型別</param>
296///<paramname="propertyName">聚合函式作用的屬性名稱</param>
297///<returns></returns>
298stringCreateConverageSql(Typetype,Converageconverage,stringpropertyName);
299
300///<summary>
301///根據實體型別來建立該實體對應資料庫表的聚合函式查詢sql語句
302///該方法建立的sql語句主要是用於統計查詢(最大值,最小值,求和,平均值,資料行數),
303///同時該sql是有條件查詢的
304///</summary>
305///<paramname="type">實體型別</param>
306///<paramname="converage">聚合函式列舉型別</param>
307///<paramname="propertyName">聚合函式作用的屬性名稱</param>
308///<paramname="dic">查詢條件屬性鍵值</param>
309///<paramname="component">查詢條件組建物件</param>
310///<returns></returns>
311stringCreateConverageSql(Typetype,Converageconverage,stringpropertyName,IDictionary<string,object>dic,outIDataParameter[]param,ConditionComponentcomponent);
312
313///<summary>
314///根據佔位符名稱建立引數
315///</summary>
316///<paramname="name">佔位符名稱</param>
317///<returns></returns>
318IDataParameterCreateParameter(stringname);
319
320///<summary>
321///根據佔位符和值建立引數
322///</summary>
323///<paramname="name">佔位符名稱</param>
324///<paramname="value">佔位符的值</param>
325///<returns></returns>
326IDataParameterCreateParameter(stringname,objectvalue);
327
328///<summary>
329///根據佔位符名稱,型別和值建立引數
330///</summary>
331///<paramname="name">佔位符名稱</param>
332///<paramname="type">引數的型別</param>
333///<paramname="value">引數的值</param>
334///<returns></returns>
335IDataParameterCreateParameter(stringname,DataTypetype,objectvalue);
336
337///<summary>
338///根據佔位符的名稱,型別和大小建立引數
339///</summary>
340///<paramname="name">佔位符名稱</param>
341///<paramname="type">引數型別</param>
342///<paramname="size">引數值大小</param>
343///<returns></returns>
344IDataParameterCreateParameter(stringname,DataTypetype,intsize);
345
346///<summary>
347///根據佔位符的名稱,型別,大小和值建立引數
348///</summary>
349///<paramname="name">佔位符名稱</param>
350///<paramname="type">引數型別</param>
351///<paramname="size">引數大小</param>
352///<paramname="value">引數值</param>
353///<returns></returns>
354IDataParameterCreateParameter(stringname,DataTypetype,intsize,objectvalue);
355
356///<summary>
357///根據佔位符名稱和型別建立引數
358///</summary>
359///<paramname="name">佔位符名稱</param>
360///<paramname="type">佔位符型別</param>
361///<returns></returns>
362IDataParameterCreateParameter(stringname,DataTypetype);
363}
364}
365

該介面定了生成增刪改查等sql語句的方法

CreateInsertSql()方法主要用於生成插入語句,該方法被過載了3次,根據各種不同的情況來生成資料庫插入sql語句。

CreateUpdateSql()方法主要用於生成修改語句,該方法被過載了7次,根據各種不同的情況來生成資料的修改sql語句。

CreateDeleteSql()方法主要用於生成刪除語句,該方法同樣被過載了7次,根據各種不同的情況來生成資料庫的刪除sql語句。

CreateSingleSql()方法主要用於生成查詢單個實體的sql語句,該方法被過載了5次,根據各種不同的情況來生成資料庫的單資料行sql語句。

CreateQuerySql()方法主要用於生成查詢集合的sql語句,該方法只被過載了一次,從上面的原始碼中可以看出,該方法只有一個Type型別引數,此方法不做正在意義上查詢使用,此方法在配合級聯查詢的時候能夠起到重要的作用。

CreateQueryByPropertySql()方法主要生成條件查詢的sql語句,該方法被充值了3次,根據不同的情況來生成資料的集合查詢的sql語句。注意該方法中引入了一個新的物件ConditionComponent,在後面的說明中對次類進行講解。

CreateConverageSql()方法主要用於生成查詢聚合函式的sql語句,該方法同樣被過載了3次,根據不同的情況來生成查詢聚合函式的sql語句。該方法同樣也引入了一個新的物件Converage,在後面的說明中對次類進行講解。

CreateParameter()方法主要用於生成sql語句佔位符引數的,該方法被過載了6次。

以上是該核心介面定義的幾組方法,用於生成sql語句。在程式設計的過程中,都採用的面向介面來程式設計,目前來說只支援sql server資料的sql語句生成,但是考慮到後期的補充,覺得在使用介面程式設計就尤為重要。後期的工作就是根據不同的資料庫去實現該介面中的所有方法。

  1. 3.插入sql語句的生成

上面說到了插入sql語句被過載了3次,在很多情況下我們根據情況的不同生成sql語句所需的方式也不同,於是歸納成了三個過載方法,該三個過載放一般情況下是可以覆蓋所有的生成插入語句的情況。

stringCreateInsertSql(IEntityentity,outIDataParameter[] param);

在上面的橋樑對映過程中,我們提到了一個介面IEntity,它是所有實體的父級介面,該介面並未定義任何方法,或許當時有人認為這是多此一舉,不過現在大家應該明白了,這樣定義是有緣由的。因為這個插入語句的生成要覆蓋所有的實體類,於是我們必須抽象出來,抽象它們共同擁有的特性。在這裡,這個IEntity介面的重要性顯得尤為突出。Param引數這是用於儲存sql語句的佔位符的,看到這個引數的修飾符out,說明引數傳入本身是空的,也就是說在後期的實現過程中我們要動態的去給param賦值,引數名,引數值,以及陣列的長度都是由entity來決定。

stringCreateInsertSql(Typetype,objectvalue,outIDataParameter[] param);

說到過載,這是面向物件程式設計的四要素之一,多型表現形式之一,另外一種是重寫。過載其實要實現的功能是一樣,只是表現形式不同而已,這裡使用了Type,這裡就是要插入的實體的型別,後面的object value就是實體,緊接著的引數就不用多說了,上面的方法已經提到過。

stringCreateInsertSql<T>(T t,outIDataParameter[] param)whereT :IEntity

說到這個過載方法,大家一般都會很興奮,為什麼.我第一眼看到了<T>,.net中的泛型。.net中的泛型我可以說真的是無懈可擊,那各種形態的使用方式是如此的婀娜多姿,總是讓程式設計師沉迷於其中的美妙,最起碼我是這樣的。後面的whereT :IEntity就是泛型約束了,泛型約束可以讓我們的程式減少很多不必要的麻煩。因為泛型本身就是一種不確定的型別,我們規定了他使用的範圍,這樣能夠減少它出錯的可能性。

下面看看這個插入sql的生成核心程式碼:

插入sql的生成核心程式碼

當大家看到這裡肯定也覺得,原理這個東西也不過如此。如果真是這樣,那我也就替你高興了,因為我要傳達的意思你已經明白了,也就是說我寫這邊博文的傳達的資訊你收到了。一次完美的會話完成。

StringBuildersbColumn =newStringBuilder("");

StringBuildersbValues =newStringBuilder("");

程式碼中定義了這兩個類,不使用string的原因大家也知道。還有這裡我們生成sql語句的規則就是sql語句插入的語法規則,這裡不再多說。

  1. 4.修改sql語句

生成修改sql語句的方法CreateUpdateSql()被過載了七次,其實生成sql語句的原理和上面生成插入sql語句的原理是一樣的。關鍵在於如何去抽象一個多情況下處理方式。

stringCreateUpdateSql(IEntityentity,outIDataParameter[] param);

這個方法主要是根據實體的主鍵作為條件來修改

stringCreateUpdateSql(IEntityentity,outIDataParameter[] param,string[] propertyNames);

這個方法則是根據實體的過個屬性來修改,各個條件以and方式來連線生成sql語句。在生成sql語句的過程中IEntity必須包含這些資料,而且這些屬性值必須存在,否則會丟擲異常。與此類似的方法還有隻有一個屬性名來修改的,其實這個方法可以包括只有一個屬性的修改方法,而這裡過載一次就是為了使用方便。

stringCreateUpdateSql(IEntityentity,outIDataParameter[] param,ConditionComponentcomponent);

這裡我們不介紹其他東西了,主要看看ConditionComponent這個類。上面提到過如果多條件修改sql語句,各個屬性都是通過and來連線的,如果我們修改使用or或者其他的方式怎麼辦,ConditionComponent可以用來解決此問題。

首先看看這個類的原始碼:

查詢元件儲存器原始碼

這個類其實就相當於一個儲存器。

privateIDictionary<string,SearchComponent> dicComponent =null;

而dicComponent就是用於儲存相應的資料的,而且是以鍵值對的方式儲存,這樣便於後面使用過程中的查詢。而這裡又出現了一個心得類SearchComponent,這個是查詢條件組建。下面在講解。這裡定義了這個類的一個單例模式,也就是說只能允許一個物件的存在每次。我需要在每次天際引數的同時這個物件仍然存在,並且儲存資訊。

publicConditionComponentAddComponent(stringpropertyName,SearchComponentcomponent)

{

if(component ==null)

{

ConditionComponent.component = Instance();

}

ConditionComponent.component.DicComponent.Add(propertyName, component);

returnConditionComponent.component;

}

這個方法每次給ConditionComponent新增一個引數,然後又返回這個物件。

下面看看上面的提到的SearchComponent原始碼:

查詢元件列舉

這裡的程式碼大家一看也就明白了,為什麼叫查詢元件了,它其實就是封裝了一些查詢可能出現的情況。程式碼非常簡單,這裡不再過多講解。

下面是生成修改語句的方法實現,這個方法的程式碼包含了查詢元件的運用:

修改sql語句的實現
  1. 5.聚合函式的使用

這裡不做過多的降解了,都是前篇一律的,不過有個特殊的地方,那就是剛才提到過來的Converage。

先看看這個列舉的原始碼:

聚合函式Converage列舉

該程式碼中定義了最和函式取最大值和最小值,聚合函式求和,聚合函式查詢行數,聚合函式求平均值。

下面是聚合函式sql語句生成的程式碼實現:

聚合函式sql語句生成的程式碼實現
  1. 6.引數佔位符

在這個生成sql語句的組建方法中,我們不斷使用了IDataParameter這個物件,這個物件或許我們看了很陌生,我們用得非常少.(糾正一下是介面),在查詢sql Server資料的時候我們經常使用的一個類SqlParameter,看到這兩個名稱如此相似,我們應該也想到了他們是什麼關係。因為我們不確定是使用什麼資料庫,可能是Sql Server,可能是Oracle,還有肯能是Access,所以使用IDataParameter是比較保險的一種方式。在這個方法中我們也看到了一個新的型別—DataType,它定義了資料庫中常用25中型別於.net中資料型別的對應列表。

下面是原始碼解析:

資料型別對應列舉列表

以上資料型別都是在程式設計中比較常用的,而且在我們在程式設計的時候,往往都會遇到型別不是完全匹配的時候,在後面的章節中將特殊的講解一個數據型別與資料型別的不同。在使用CreateParameter() 建立佔位符引數的時候,我們也要轉化一下型別。之前我們使用SqlParameter 的時候,很多人就是new SqlParameter("@name","qingyuan") 這樣對應。就預設為string 型別可以直接轉化為sql中的nvarchar,varchar等型別,其實不然。中間還有一個轉化過程。

.net 與SQL 型別的相互轉化

所以說做程式不能只看到表面現象,只有深入的去了解他們的原理,知識的使用才能遊刃有餘。即使千變萬化,也是萬變不離其宗。

說到這篇文章,我只能說我只寫到了很膚淺的一部分。明天要去參加老趙的一個演講,我想大家都應該這道他的主題是什麼了,在文章的結尾我想說,.net 的確有他的奧妙之處。或許我們是覺得.net入門非常簡單,這些我承認。說.net 是傻瓜式程式設計,其實是不是傻瓜式程式設計這個不是由語言決定的,關鍵在於你怎麼去使用這個東西。C# 的確是一門非常優美的語言,我只能以這種言辭來表達。各種語言程式設計都有他的好處和壞處,不能從單一角度出發,只有你深入的瞭解了你就會發現它的美。

(注: ORM涉及內容比較多,後續期待,有興趣的可以與本人探討)