中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

EF架構(gou)~性能(neng)高效的批(pi)量操作(Update篇)

回到目錄

很多時間之長,我寫了EF架構~性能高效的批量操作(Insert篇),而今天我(wo)把(ba)Update篇也寫一(yi)下(xia),這(zhe)對(dui)于批量處(chu)理數(shu)據(ju)很有幫助,它解(jie)決了EF與(yu)linq to sql批量更(geng)新數(shu)據(ju)上(shang)的效(xiao)率問(wen)題。

對于EF架構(gou)中的批(pi)量更新操(cao)作,需要我(wo)們為實體的導航屬(shu)性(xing)進(jin)行(xing)手動的標示,因為EF生(sheng)成的實體中沒有一個特殊的說明,所以,我(wo)們必(bi)須(xu)要告訴系統,哪個屬(shu)性(xing)是(shi)導航屬(shu)性(xing),而導航屬(shu)性(xing)是(shi)我(wo)們不去進(jin)行(xing)update的。

1    /// <summary>
2     /// 屬性的導航屬性
3     /// </summary>
4     public class NavigationAttribute : Attribute
5     {
6 
7     }

而(er)對于要進行批(pi)量更新(xin)的實體,我(wo)們需要為(wei)導(dao)航屬(shu)性添加(jia)這個特性

1    public class User
2     {
3         public int UserID { get; set; }
4         [Navigation]
5         public User_Extension User_Extension { get; set; }
6     }

而對(dui)于我們(men)構建批量Update語(yu)句,請看代碼,它需要對(dui)導(dao)航屬(shu)性(xing)進(jin)行過濾

 1         /// <summary>
 2         /// 構建Update語句串(chuan)
 3         /// </summary>
 4         /// <typeparam name="TEntity"></typeparam>
 5         /// <param name="entity"></param>
 6         /// <returns></returns>
 7         private Tuple<string, object[]> CreateUpdateSQL<TEntity>(TEntity entity) where TEntity : class
 8         {
 9             if (entity == null)
10                 throw new ArgumentException("The database entity can not be null.");
11             List<string> pkList = GetPrimaryKey<TEntity>().Select(i => i.Name).ToList();
12 
13             Type entityType = entity.GetType();
14             var table = entityType.GetProperties().Where(i =>
15                 !pkList.Contains(i.Name)
16                 && i.GetValue(entity, null) != null
17                 && i.PropertyType != typeof(EntityState)
18                 && !(i.GetCustomAttributes(false).Length > 0
19                 && i.GetCustomAttributes(false).Where(j => j.GetType() == typeof(NavigationAttribute)) != null)
20                 && (i.PropertyType.IsValueType || i.PropertyType == typeof(string)) //過濾導航(hang)屬性
21                  ).ToArray();
22 
23             //過濾主鍵,航(hang)行(xing)屬(shu)性,狀態屬(shu)性等
24             if (pkList == null || pkList.Count == 0)
25                 throw new ArgumentException("The Table entity have not a primary key.");
26             List<object> arguments = new List<object>();
27             StringBuilder builder = new StringBuilder();
28 
29             foreach (var change in table)
30             {
31                 if (pkList.Contains(change.Name))
32                     continue;
33                 if (arguments.Count != 0)
34                     builder.Append(", ");
35                 builder.Append(change.Name + " = {" + arguments.Count + "}");
36                 if (change.PropertyType == typeof(string) || change.PropertyType == typeof(DateTime))
37                     arguments.Add("'" + change.GetValue(entity, null).ToString().Replace("'", "char(39)") + "'");
38                 else
39                     arguments.Add(change.GetValue(entity, null));
40             }
41 
42             if (builder.Length == 0)
43                 throw new Exception("沒(mei)有任何屬性進(jin)行更(geng)新");
44 
45             builder.Insert(0, " UPDATE " + string.Format("[{0}]", entityType.Name) + " SET ");
46 
47             builder.Append(" WHERE ");
48             bool firstPrimaryKey = true;
49 
50             foreach (var primaryField in pkList)
51             {
52                 if (firstPrimaryKey)
53                     firstPrimaryKey = false;
54                 else
55                     builder.Append(" AND ");
56 
57                 object val = entityType.GetProperty(primaryField).GetValue(entity, null);
58                 builder.Append(GetEqualStatment(primaryField, arguments.Count));
59                 arguments.Add(val);
60             }
61             return new Tuple<string, object[]>(builder.ToString(), arguments.ToArray());
62 
63         }

而(er)對子類公開的Update方(fang)法,我(wo)們進行了一個(ge)封裝,它(ta)通過操作枚舉(ju)來確實你是(shi)要insert,update還是(shi)delete,看代碼

 1         /// <summary>
 2         /// 執(zhi)行SQL,根據SQL操作(zuo)的類型
 3         /// </summary>
 4         /// <typeparam name="TEntity"&gt;</typeparam>
 5         /// <param name="list"></param>
 6         /// <param name="sqlType"></param>
 7         /// <returns></returns>
 8         protected string DoSQL<TEntity>(IEnumerable<TEntity> list, SQLType sqlType) where TEntity : class
 9         {
10             StringBuilder sqlstr = new StringBuilder();
11             switch (sqlType)
12             {
13                 case SQLType.Insert:
14                     list.ToList().ForEach(i =>
15                     {
16                         Tuple<string, object[]> sql = CreateInsertSQL(i);
17                         sqlstr.AppendFormat(sql.Item1, sql.Item2);
18                     });
19                     break;
20                 case SQLType.Update:
21                     list.ToList().ForEach(i =>
22                     {
23                         Tuple<string, object[]> sql = CreateUpdateSQL(i);
24                         sqlstr.AppendFormat(sql.Item1, sql.Item2);
25                     });
26                     break;
27                 case SQLType.Delete:
28                     list.ToList().ForEach(i =>
29                     {
30                         Tuple<string, object[]> sql = CreateDeleteSQL(i);
31                         sqlstr.AppendFormat(sql.Item1, sql.Item2);
32                     });
33                     break;
34                 default:
35                     throw new ArgumentException("請輸(shu)入正確的參數(shu)");
36             }
37             return sqlstr.ToString();
38         }

代碼完成,這個批量操作經過測試,在速度上遠遠超過EF自帶的方法,原因,當然是減少了與數據庫交互的次數。

回到目錄

posted @ 2013-01-10 16:46  張占嶺  閱讀(28184)  評論(11)    收藏  舉報