Linq2sql泛型增删改查
linq2sql常规的增删改查方法如下
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
1 //增
2 var a = new A();
3 //给a赋值…
4 _ctx.A. InsertOnSubmit(a);
5 _ctx.SubmitChanges(ConflictMode.FailOnFirstConflict);
6 //删
7 _ctx.A. DeleteOnSubmit(a);
8 _ctx.SubmitChanges(ConflictMode.FailOnFirstConflict);
9 //改
10 //改变a的值…
11 _ctx.SubmitChanges(ConflictMode.FailOnFirstConflict);
12 //查
13 _ctx.A.Where(a =>a.ObjId == objId). SingleOrDefault();
所有实体类都是采用这样的一个方法,这样的好处在于所有的类和属性都是强类型,只要映射实体的属性与数据库保持同步,就不会出现sql语句层面的错误。但是如果在大型项目中应用,需要维护的实体类超过一定数量,数据访问层写这些基本的方法都会是一个非常庞大的工作,以后的维护升级也会是非常困难的事情。能不能将这些常用的方法封装起来,变成一个可通用的方法。经过研究,发现利用泛型方法可以实现。这些代码可以放在数据访问层中,实现代码如下
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
1 /// <summary>
2 /// 保存实体类
3 /// </summary>
4 /// <typeparam name="T"></typeparam>
5 /// <param name="t"></param>
6 /// <returns></returns>
7 public bool SaveEntity<T>(T t)
8 where T : class
9 {
10 ValidateType<T>();
11 _ctx.GetTable(typeof(T)).InsertOnSubmit(t);
12 return SubmitToDB();
13 }
14
15 /// <summary>
16 /// 保存实体类集合
17 /// </summary>
18 /// <typeparam name="T"></typeparam>
19 /// <param name="list"></param>
20 /// <returns></returns>
21 public bool SaveEntities<T>(IList<T> list)
22 where T : class
23 {
24 ValidateType<T>();
25 _ctx.GetTable(typeof(T)).InsertAllOnSubmit(list);
26 return SubmitToDB();
27
28 }
29
30 /// <summary>
31 /// 更新实体类
32 /// </summary>
33 /// <typeparam name="T"></typeparam>
34 /// <param name="t"></param>
35 /// <returns></returns>
36 public bool UpdateEntity<T>(T t)
37 where T : class
38 {
39 ValidateType<T>();
40 return SubmitToDB();
41 }
42
43 /// <summary>
44 /// 删除实体类,注意只能用于ProjectManagement库中的表实体
45 /// </summary>
46 /// <typeparam name="T"></typeparam>
47 /// <param name="t"></param>
48 /// <returns></returns>
49 public bool DeleteEntity<T>(T t)
50 where T : class
51 {
52 ValidateType<T>();
53 _ctx.GetTable(typeof(T)).DeleteOnSubmit(t);
54 return SubmitToDB();
55 }
56
57 /// <summary>
58 /// 删除实体类集合
59 /// </summary>
60 /// <typeparam name="T"></typeparam>
61 /// <param name="list"></param>
62 /// <returns></returns>
63 public bool DeleteEntities<T>(IList<T> list)
64 where T : class
65 {
66 ValidateType<T>();
67 foreach(T t in list)
68 _ctx.GetTable(typeof(T)).DeleteOnSubmit(t);
69 return SubmitToDB();
70 }
71
72 /// <summary>
73 /// 根据实体Id获取实体对象
74 /// </summary>
75 /// <typeparam name="T">实体类型</typeparam>
76 /// <param name="id">实体Id</param>
77 /// <returns>实体对象</returns>
78 public T GetEntityById<T>(int id)
79 where T : class
80 {
81 ValidateType<T>();
82
83 MetaTable table = _ctx.Mapping.GetTable(typeof(T));
84 var key = table.RowType.DataMembers.Single<MetaDataMember>(c => c.IsPrimaryKey).MappedName;
85 if (string.IsNullOrEmpty(key))
86 return default(T);
87
88
89 //这里也可以换成return _ctx.GetTable(typeof(T)).Where(key+"="+id).SingleOrDefault();
90 string sql = "select * from " + table.TableName + " where " + key + " = " + "{0}";
91 Object[] param = new Object[1] { id };
92 return _ctx.ExecuteQuery<T>(sql, param).SingleOrDefault();
93 }
94
95 /// <summary>
96 /// 根据实体
97 /// </summary>
98 /// <typeparam name="T"></typeparam>
99 /// <param name="predicate">lambda表达式</param>
100 /// <returns>实体列表</returns>
101 public IList<T> GetEntities<T>(Expression<Func<T, bool>> predicate)
102 where T : class
103 {
104 ValidateType<T>();
105 return _ctx.GetTable<T>().Where(predicate).ToList();
106 }
107 /// <summary>
108 /// 验证泛型实体的类型
109 /// </summary>
110 /// <typeparam name="T">泛型类型</typeparam>
111 private void ValidateType<T>()
112 {
113
114 Type type = typeof(T);
115 if (type.Namespace != typeof(DataContext).Namespace)
116 throw new ArgumentException("传入的泛型对象类型不属于Data实体");
117 }
118
119 /// <summary>
120 /// 将添加、删除、修改的命令提交至数据库执行
121 /// </summary>
122 /// <returns>执行是否成功</returns>
123 private bool SubmitToDB()
124 {
125 bool success = false;
126 try
127 {
128 _ctx.SubmitChanges(ConflictMode.FailOnFirstConflict);
129 success = true;
130 }
131 catch (Exception err)
132 {
133 logger.Error(err.Message + err.StackTrace);
134 success = false;
135 }
136 return success;
137 }
138
139
其实也可以利用动态扩展方法,将这些方法作为DataContext类的扩展,干净的注入DataContext。动态扩展方法是C#3.0的新特性,Dynamic的类库也是使用这个方式来扩展IQueryable,如通lamda表达式一般,非常的优雅和精妙。
public static class EntityExtension
{
public static bool Save<T>(this DataContext ctx,T t) where t : class
{
//实现部分与之前类似
}
}
{
public static bool Save<T>(this DataContext ctx,T t) where t : class
{
//实现部分与之前类似
}
}