前两篇简单谈了一些.net core的优势以及机构设计的一些思路,这一篇开始,我们将从零开始搭建架构,底层我们将采用ef来访问数据库,所以这篇我们将贴一下ef常用操作的基类。

     

    简单介绍下一些类库将要实现的功能:

           business:业务实现层

           domains:实体(model)

           service:接口

           data:数据库访问(ef或其他)

           easycacheing:开源缓存管理

           tools:工具类库

    其他的我们用到的时候再说;

    接着说ef常用操作基类,我们将基类放在data下,具体目录结构如下:

    

   baseentity:实体基类,基础共有的放在这里面:

 1 using system;
 2 using system.collections.generic;
 3 using system.text;
 4 
 5 namespace data
 6 {
 7     /// <summary>
 8     /// base class for entities
 9     /// </summary>
10     ///[serializable]
11     public abstract partial class baseentity
12     {
13         /// <summary>
14         /// gets or sets the entity identifier
15         /// </summary>
16         public string id { get; set; }
17         public virtual nullable<datetime> createtime { get; set; }
18         public virtual string createperson { get; set; }
19         public virtual nullable<datetime> updatetime { get; set; }
20         public virtual string updateperson { get; set; }
21 
22         public baseentity()
23         {
24             this.id = getidentifier();
25             this.createtime = datetime.now;
26             this.updatetime = datetime.now;
27         }
28 
29         private string getidentifier()
30         {
31             return guid.newguid().tostring();
32         }
33 
34         public override bool equals(object obj)
35         {
36             return equals(obj as baseentity);
37         }
38 
39         private static bool istransient(baseentity obj)
40         {
41             return obj != null && equals(obj.id, default(string));
42         }
43 
44         private type getunproxiedtype()
45         {
46             return gettype();
47         }
48 
49         public virtual bool equals(baseentity other)
50         {
51             if (other == null)
52                 return false;
53 
54             if (referenceequals(this, other))
55                 return true;
56 
57             if (!istransient(this) &&
58                 !istransient(other) &&
59                 equals(id, other.id))
60             {
61                 var othertype = other.getunproxiedtype();
62                 var thistype = getunproxiedtype();
63                 return thistype.isassignablefrom(othertype) ||
64                         othertype.isassignablefrom(thistype);
65             }
66 
67             return false;
68         }
69 
70         public static bool operator ==(baseentity x, baseentity y)
71         {
72             return equals(x, y);
73         }
74 
75         public static bool operator !=(baseentity x, baseentity y)
76         {
77             return !(x == y);
78         }
79     }
80 }

       dbcontextextensions:数据库操作扩展

 1 using microsoft.entityframeworkcore;
 2 using microsoft.entityframeworkcore.infrastructure;
 3 using system;
 4 using system.collections.generic;
 5 using system.data;
 6 using system.data.common;
 7 using system.data.sqlclient;
 8 using system.reflection;
 9 using system.text;
10 
11 namespace data
12 {
13     public static class dbcontextextensions
14     {
15         private static void combineparams(ref dbcommand command, params object[] parameters)
16         {
17             if (parameters != null)
18             {
19                 foreach (sqlparameter parameter in parameters)
20                 {
21                     if (!parameter.parametername.contains("@"))
22                         parameter.parametername = $"@{parameter.parametername}";
23                     command.parameters.add(parameter);
24                 }
25             }
26         }
27       
28         
29         private static dbcommand createcommand(databasefacade facade, string sql, out dbconnection dbconn, params object[] parameters)
30         {
31             dbconnection conn = facade.getdbconnection();
32             dbconn = conn;
33             conn.open();
34             dbcommand cmd = conn.createcommand();
35             if (facade.issqlserver())
36             {
37                 cmd.commandtext = sql;
38                 combineparams(ref cmd, parameters);
39             }
40             return cmd;
41         }
42 
43         public static datatable sqlquery(this databasefacade facade, string sql, params object[] parameters)
44         {
45             dbcommand cmd = createcommand(facade, sql, out dbconnection conn, parameters);
46             dbdatareader reader = cmd.executereader();
47             datatable dt = new datatable();
48             dt.load(reader);
49             reader.close();
50             conn.close();
51             return dt;
52         }
53 
54         public static ienumerable<t> sqlquery<t>(this databasefacade facade, string sql, params object[] parameters) where t : class, new()
55         {
56             datatable dt = sqlquery(facade, sql, parameters);
57             return dt.toenumerable<t>();
58         }
59      
60         public static ienumerable<t> toenumerable<t>(this datatable dt) where t : class, new()
61         {
62             propertyinfo[] propertyinfos = typeof(t).getproperties();
63             t[] ts = new t[dt.rows.count];
64             int i = 0;
65             foreach (datarow row in dt.rows)
66             {
67                 t t = new t();
68                 foreach (propertyinfo p in propertyinfos)
69                 {
70                     if (dt.columns.indexof(p.name) != -1 && row[p.name] != dbnull.value)
71                         p.setvalue(t, row[p.name], null);
72                 }
73                 ts[i] = t;
74                 i++;
75             }
76             return ts;
77         }
78     }
79 }

        ipagedlist:分页接口

 1 using system;
 2 using system.collections.generic;
 3 using system.text;
 4 
 5 namespace data
 6 {
 7     public interface ipagedlist<t> : ilist<t>
 8     {
 9         int pageindex { get; }
10         int pagesize { get; }
11         int totalcount { get; }
12         int totalpages { get; }
13         bool haspreviouspage { get; }
14         bool hasnextpage { get; }
15     }
16 }

       pagedlist:分页接口的实现

 1 using system;
 2 using system.collections.generic;
 3 using system.linq;
 4 using system.text;
 5 
 6 namespace data
 7 {
 8     /// <summary>
 9     /// paged list
10     /// </summary>
11     /// <typeparam name="t">t</typeparam>
12     public class pagedlist<t> : list<t>, ipagedlist<t>
13     {
14         /// <summary>
15         /// ctor
16         /// </summary>
17         /// <param name="source">source</param>
18         /// <param name="pageindex">page index</param>
19         /// <param name="pagesize">page size</param>
20         public pagedlist(iqueryable<t> source, int pageindex, int pagesize)
21         {
22             int total = source.count();
23             this.totalcount = total;
24             this.totalpages = total / pagesize;
25 
26             if (total % pagesize > 0)
27                 totalpages++;
28 
29             this.pagesize = pagesize;
30             this.pageindex = pageindex;
31             this.addrange(source.skip((pageindex - 1) * pagesize).take(pagesize).tolist());
32         }
33 
34         /// <summary>
35         /// ctor
36         /// </summary>
37         /// <param name="source">source</param>
38         /// <param name="pageindex">page index</param>
39         /// <param name="pagesize">page size</param>
40         public pagedlist(ilist<t> source, int pageindex, int pagesize)
41         {
42             totalcount = source.count();
43             totalpages = totalcount / pagesize;
44 
45             if (totalcount % pagesize > 0)
46                 totalpages++;
47 
48             this.pagesize = pagesize;
49             this.pageindex = pageindex;
50             this.addrange(source.skip((pageindex - 1) * pagesize).take(pagesize).tolist());
51         }
52 
53         /// <summary>
54         /// ctor
55         /// </summary>
56         /// <param name="source">source</param>
57         /// <param name="pageindex">page index</param>
58         /// <param name="pagesize">page size</param>
59         /// <param name="totalcount">total count</param>
60         public pagedlist(ienumerable<t> source, int pageindex, int pagesize, int totalcount)
61         {
62             totalcount = totalcount;
63             totalpages = totalcount / pagesize;
64 
65             if (totalcount % pagesize > 0)
66                 totalpages++;
67 
68             this.pagesize = pagesize;
69             this.pageindex = pageindex;
70             this.addrange(source);
71         }
72 
73         public int pageindex { get; private set; }
74         public int pagesize { get; private set; }
75         public int totalcount { get; private set; }
76         public int totalpages { get; private set; }
77 
78         public bool haspreviouspage
79         {
80             get { return (pageindex > 0); }
81         }
82         public bool hasnextpage
83         {
84             get { return (pageindex + 1 < totalpages); }
85         }
86     }
87 }

         ienumerableextensions:ienumerable分页的扩展

 1 using system.collections.generic;
 2 using system.linq;
 3 
 4 namespace data
 5 {
 6     public static class ienumerableextensions
 7     {
 8         public static pagedlist<tsource> topagelist<tsource>(this ienumerable<tsource> source, int pageindex, int pagesize)
 9         {
10             if (pageindex < 1)
11                 pageindex = 1;
12             int totalcount = 0;
13             list<tsource> resultlist = new list<tsource>();
14             resultlist = source.skip((pageindex - 1) * pagesize).take(pagesize).tolist(); ;
15             totalcount = source.count();
16             return new pagedlist<tsource>(resultlist, pageindex, pagesize, totalcount);
17         }
18     }
19 }

        irepository:数据库仓库访问接口

  1 using system;
  2 using system.collections.generic;
  3 using system.linq;
  4 using system.linq.expressions;
  5 
  6 namespace data
  7 {
  8     public interface irepository<t> where t : baseentity
  9     {
 10         /// <summary>
 11         /// 通过id获取单个实体
 12         /// </summary>
 13         /// <param name="id"></param>
 14         /// <returns></returns>
 15         t getbyid(object id);
 16         /// <summary>
 17         /// 插入单个实体
 18         /// </summary>
 19         /// <param name="entity">实体</param>
 20         /// <returns></returns>
 21         bool insert(t entity);
 22         /// <summary>
 23         /// 插入单个实体并返回id
 24         /// </summary>
 25         /// <param name="entity"></param>
 26         /// <returns></returns>
 27         object insertandgetid(t entity);
 28         /// <summary>
 29         /// 批量插入数据集
 30         /// </summary>
 31         /// <param name="entities">数据集</param>
 32         void insert(ienumerable<t> entities);
 33         /// <summary>
 34         /// 更新单个实体
 35         /// </summary>
 36         /// <param name="entity">实体</param>
 37         /// <returns></returns>
 38         bool update(t entity);
 39         /// <summary>
 40         /// 批量更新数据集
 41         /// </summary>
 42         /// <param name="entities"></param>
 43         void update(ienumerable<t> entities);
 44         /// <summary>
 45         /// 删除单个实体
 46         /// </summary>
 47         /// <param name="entity"></param>
 48         /// <returns></returns>
 49         bool delete(t entity);
 50         /// <summary>
 51         /// 批量删除
 52         /// </summary>
 53         /// <param name="entities">删除的数据集</param>
 54         void delete(ienumerable<t> entities);
 55         /// <summary>
 56         /// 通过id删除实体
 57         /// </summary>
 58         /// <param name="id"></param>
 59         /// <returns></returns>
 60         bool deletebyid(object id);
 61         /// <summary>
 62         /// 通过id(逗号分隔id)批量删除
 63         /// </summary>
 64         /// <param name="ids"></param>
 65         /// <returns></returns>
 66         bool deletebyids(object ids);
 67         /// <summary>
 68         /// 通过id列表批量删除
 69         /// </summary>
 70         /// <param name="list"></param>
 71         /// <returns></returns>
 72         bool deletebyidlist(list<object> list);
 73         /// <summary>
 74         /// 分页查询
 75         /// </summary>
 76         /// <param name="pageindex">当前页</param>
 77         /// <param name="pagesize">每页条数</param>
 78         /// <param name="condition">lambda查询条件where</param>
 79         /// <param name="ordername">排序字段 默认createtime</param>
 80         /// <param name="sortorder">排序方式 asc desc,默认createtime desc</param>
 81         /// <returns></returns>
 82         ipagedlist<t> getlistforpaging(int pageindex, int pagesize, expression<func<t, bool>> condition = null, string ordername = null, string sortorder = null);
 83         /// <summary>
 84         /// linq连表查询专用,获取单表所有数据请使用getlist
 85         /// </summary>
 86         iqueryable<t> table { get; }
 87         /// <summary>
 88         /// 根据条件查找
 89         /// </summary>
 90         /// <param name="condition">lambda查询条件where</param>
 91         /// <returns></returns>
 92         t getentity(expression<func<t, bool>> condition);
 93         /// <summary>
 94         /// 分页查询(linq分页方式)
 95         /// </summary>
 96         /// <param name="pageindex">当前页</param>
 97         /// <param name="pagesize">页码</param>
 98         /// <param name="condition">lambda查询条件where</param>
 99         /// <<param name="sort">排序key:排序字段,value:bool,true-desc,false-asc 默认:createtime desc</param>
100         /// <returns></returns>
101         ipagedlist<t> getlistforpaging(int pageindex, int pagesize, expression<func<t, bool>> condition = null, dictionary<string, bool> sort = null);
102         /// <summary>  
103         /// 执行原始sql命令  
104         /// </summary>  
105         /// <param name="commandtext">sql命令</param>  
106         /// <param name="parameters">参数</param>  
107         /// <returns>影响的记录数</returns>  
108         ienumerable<telement> sqlquery<telement>(string sql, params object[] parameters) where telement : class, new();
109         /// <summary>
110         /// 执行sqlcommand
111         /// </summary>
112         /// <param name="sql">sql</param>
113         /// <param name="parameters">参数</param>
114         /// <returns></returns>
115         int executesqlcommand(string sql, params object[] parameters);
116         /// <summary>
117         /// 查询列表,默认返回整个表数据
118         /// </summary>
119         /// <param name="condition">lambda查询条件where</param>
120         /// <returns></returns>
121         list<t> getlist(expression<func<t, bool>> condition = null);
122     }
123 }

       efrepository:iefrepository接口实现

  1 using microsoft.entityframeworkcore;
2 using system;
3 using system.collections.generic;
4 using system.data;
5 using system.linq;
6 using system.linq.expressions;
7 using system.reflection;
8 using tools.cache;
9 
10 namespace data
11 {
12     public class efrepository<t> : irepository<t> where t : baseentity
13     {
14         private dbcontext _context;
15         private dbset<t> _entities;
16         private istaticcachemanager _cachemanager;
17         public efrepository(dbcontext context, istaticcachemanager cachemanager)
18         {
19             this._context = context;
20             _cachemanager = cachemanager;
21         }
22 
23         private dbset<t> entities
24         {
25             get
26             {
27                 if (_entities == null)
28                 {
29                     _entities = this._context.set<t>();
30                 }     
31                 return _entities;
32             }
33         }
34         /// <summary>
35         /// linq连表查询专用,获取单表所有数据请使用getlist
36         /// </summary>
37         public virtual iqueryable<t> table
38         {
39             get {
40                 return this.entities;
41             }
42         }
43         /// <summary>
44         /// 通过id获取单个实体
45         /// </summary>
46         /// <param name="id"></param>
47         /// <returns></returns>
48         public virtual t getbyid(object id)
49         {
50             var cachekey = typeof(t).name+".getbyid."+id;
51             return _cachemanager.get(cachekey, ()=>this.entities.find(id));
52         }
53         /// <summary>
54         /// 插入单个实体
55         /// </summary>
56         /// <param name="entity">实体</param>
57         /// <returns></returns>
58         public virtual bool insert(t entity)
59         {
60             if (entity == null)
61                 throw new argumentnullexception(nameof(entity));
62 
63             try
64             {
65                 entities.add(entity);
66                 _context.savechanges();
67                 var cachecontain = typeof(t).name;
68                 _cachemanager.removebycontain(cachecontain);
69             }
70             catch (dbupdateexception exception)
71             {
72                 //ensure that the detailed error text is saved in the log
73                 throw new exception(getfullerrortextandrollbackentitychanges(exception), exception);
74             }
75             return true;
76         }
77         /// <summary>
78         /// 插入单个实体并返回id
79         /// </summary>
80         /// <param name="entity"></param>
81         /// <returns></returns>
82         public virtual object insertandgetid(t entity)
83         {
84             if (entity == null)
85                 throw new argumentnullexception(nameof(entity));
86             try
87             {
88                 this.entities.add(entity);
89                 this._context.savechanges();
90                 var cachecontain = typeof(t).name;
91                 _cachemanager.removebycontain(cachecontain);
92             }
93             catch (dbupdateexception exception)
94             {
95                 //ensure that the detailed error text is saved in the log
96                 throw new exception(getfullerrortextandrollbackentitychanges(exception), exception);
97             }
98             return entity.id;
99         }
100         /// <summary>
101         /// 批量插入数据集
102         /// </summary>
103         /// <param name="entities">数据集</param>
104         public virtual void insert(ienumerable<t> entities)
105         {
106             if (entities == null)
107                 throw new argumentnullexception(nameof(entities));
108 
109             try
110             {
111                 entities.addrange(entities);
112                 _context.savechanges();
113                 var cachecontain = typeof(t).name;
114                 _cachemanager.removebycontain(cachecontain);
115             }
116             catch (dbupdateexception exception)
117             {
118                 //ensure that the detailed error text is saved in the log
119                 throw new exception(getfullerrortextandrollbackentitychanges(exception), exception);
120             }
121         }
122         /// <summary>
123         /// 更新单个实体
124         /// </summary>
125         /// <param name="entity">实体</param>
126         /// <returns></returns>
127         public virtual bool update(t entity)
128         {
129             if (entity == null)
130                 throw new argumentnullexception(nameof(entity));
131             try
132             {
133                 this._context.set<t>().attach(entity);
134                 type _type = typeof(t);
135                 propertyinfo[] _properties = _type.getproperties();
136                 var entry = _context.entry(entity);
137                 foreach (propertyinfo item in _properties)
138                 {
139                     if ("id" == item.name || "createtime" == item.name || "createperson" == item.name)
140                     {
141                         continue;
142                     }
143                   
144                     entry.property(item.name).ismodified = true;
145                 }
146                 this._context.savechanges();
147                 var cachecontain = typeof(t).name;
148                 _cachemanager.removebycontain(cachecontain);
149             }
150             catch (dbupdateexception exception)
151             {
152                 //ensure that the detailed error text is saved in the log
153                 throw new exception(getfullerrortextandrollbackentitychanges(exception), exception);
154             }
155             return true;
156         }
157         /// <summary>
158         /// 批量更新数据集
159         /// </summary>
160         /// <param name="entities"></param>
161         public virtual void update(ienumerable<t> entities)
162         {
163             if (entities == null)
164                 throw new argumentnullexception(nameof(entities));
165 
166             try
167             {
168                 // entities.updaterange(entities);
169                 this._context.set<t>().attachrange(entities);
170                 foreach (var entity in entities)
171                 {
172                     type _type = typeof(t);
173                     propertyinfo[] _properties = _type.getproperties();
174                     var entry = _context.entry(entity);
175                     foreach (propertyinfo item in _properties)
176                     {
177                         if ("id" == item.name || "createtime" == item.name || "createperson" == item.name)
178                         {
179                             continue;
180                         }
181 
182                         entry.property(item.name).ismodified = true;
183                     }
184                 }
185 
186                 _context.savechanges();
187                 var cachecontain = typeof(t).name;
188                 _cachemanager.removebycontain(cachecontain);
189             }
190             catch (dbupdateexception exception)
191             {
192                 //ensure that the detailed error text is saved in the log
193                 throw new exception(getfullerrortextandrollbackentitychanges(exception), exception);
194             }
195         }
196         /// <summary>
197         /// 删除单个实体
198         /// </summary>
199         /// <param name="entity"></param>
200         /// <returns></returns>
201         public virtual bool delete(t entity)
202         {
203             if (entity == null)
204                 throw new argumentnullexception(nameof(entity));
205 
206             try
207             {
208                 entities.remove(entity);
209                 _context.savechanges();
210                 var cachecontain = typeof(t).name;
211                 _cachemanager.removebycontain(cachecontain);
212             }
213             catch (dbupdateexception exception)
214             {
215                 //ensure that the detailed error text is saved in the log
216                 throw new exception(getfullerrortextandrollbackentitychanges(exception), exception);
217             }
218             return true;
219         }
220         /// <summary>
221         /// 批量删除
222         /// </summary>
223         /// <param name="entities">删除的数据集</param>
224         public virtual void delete(ienumerable<t> entities)
225         {
226             if (entities == null)
227                 throw new argumentnullexception(nameof(entities));
228 
229             try
230             {
231                 entities.removerange(entities);
232                 _context.savechanges();
233                 var cachecontain = typeof(t).name;
234                 _cachemanager.removebycontain(cachecontain);
235             }
236             catch (dbupdateexception exception)
237             {
238                 //ensure that the detailed error text is saved in the log
239                 throw new exception(getfullerrortextandrollbackentitychanges(exception), exception);
240             }
241         }
242         /// <summary>
243         /// 通过id删除实体
244         /// </summary>
245         /// <param name="id"></param>
246         /// <returns></returns>
247         public virtual bool deletebyid(object id)
248         {
249             try
250             {
251                 var item = this.entities.find(id);
252                 if (item == null)
253                 {
254                     return false;
255                 }
256                 this.entities.remove(item);
257                 this._context.savechanges();
258                 var cachecontain = typeof(t).name;
259                 _cachemanager.removebycontain(cachecontain);
260             }
261             catch (dbupdateexception exception)
262             {
263                 //ensure that the detailed error text is saved in the log
264                 throw new exception(getfullerrortextandrollbackentitychanges(exception), exception);
265             }
266             return true;
267         }
268         /// <summary>
269         /// 通过id(逗号分隔id)批量删除
270         /// </summary>
271         /// <param name="ids"></param>
272         /// <returns></returns>
273         public virtual bool deletebyids(object ids)
274         {
275             try
276             {
277                 var idarray = ids.tostring().split(',');
278                 for (int i = 0; i < idarray.length; i++)
279                 {
280                     var item = this.entities.find(idarray[i]);
281                     if (item == null)
282                     {
283                         continue;
284                     }
285                     this.entities.remove(item);
286                 }
287                 this._context.savechanges();
288                 var cachecontain = typeof(t).name;
289                 _cachemanager.removebycontain(cachecontain);
290             }
291             catch (dbupdateexception exception)
292             {
293                 //ensure that the detailed error text is saved in the log
294                 throw new exception(getfullerrortextandrollbackentitychanges(exception), exception);
295             }
296             return true;
297         }
298         /// <summary>
299         /// 通过id列表批量删除
300         /// </summary>
301         /// <param name="list"></param>
302         /// <returns></returns>
303         public virtual bool deletebyidlist(list<object> list)
304         {
305             try
306             {
307                 for (int i = 0; i < list.count; i++)
308                 {
309                     var item = this.entities.find(list[i]);
310                     if (item == null)
311                     {
312                         continue;
313                     }
314                     this.entities.remove(item);
315                 }
316                 this._context.savechanges();
317                 var cachecontain = typeof(t).name;
318                 _cachemanager.removebycontain(cachecontain);
319             }
320             catch (dbupdateexception exception)
321             {
322                 //ensure that the detailed error text is saved in the log
323                 throw new exception(getfullerrortextandrollbackentitychanges(exception), exception);
324             }
325             return true;
326         }
327 
328         /// <summary>
329         /// 根据条件查找
330         /// </summary>
331         /// <param name="condition">lambda查询条件where</param>
332         /// <returns></returns>
333         public virtual t getentity(expression<func<t, bool>> condition)
334         {
335             var cachekey = typeof(t) + "getsingleordefault.condition."+ condition.tostring();
336             return _cachemanager.get(cachekey,()=>this.entities.where(condition).singleordefault());
337         }
338         /// <summary>
339         /// 分页查询(linq分页方式)
340         /// </summary>
341         /// <param name="pageindex">当前页</param>
342         /// <param name="pagesize">页码</param>
343         /// <param name="condition">lambda查询条件where</param>
344         /// <param name="sort">排序key:排序字段,value:bool,true-desc,false-asc,默认:createtime desc</param>
345         /// <returns></returns>
346         public virtual ipagedlist<t> getlistforpaging(int pageindex, int pagesize, expression<func<t, bool>> condition = null, dictionary<string, bool> sort = null)
347         {
348             if (pageindex < 1)
349                 pageindex = 1;
350             var cachekey = typeof(t).name;
351             cachekey = cachekey + ".getlist";
352             list<t> data = null;
353 
354             if (condition != null)
355             {
356                 cachekey = cachekey+ ".condition." + condition.tostring();
357             }
358 
359             data = _cachemanager.get<list<t>>(cachekey);
360 
361             if(data != null)
362             {
363                 if (sort != null)
364                 {
365                     foreach (var item in sort)
366                     {
367                         data = data.asqueryable().orderby(item.key, item.value).tolist();
368                     }
369                 }
370                 else
371                 {
372                     data = data.asqueryable().orderbydescending(x => x.createtime).tolist();
373                 }
374             }
375             else
376             {
377                 if(condition!=null)
378                 {
379                     data = this.entities.where(condition).tolist();
380                 }
381                 else
382                 {
383                     data = this.entities.tolist();
384                 }
385                 _cachemanager.set(cachekey, data, 60);
386 
387                 data = data.asqueryable().orderbydescending(x => x.createtime).tolist();//无缓存默认返回排序后数据
388             }
389 
390             return new pagedlist<t>(data, pageindex, pagesize);
391         }
392 
393         /// <summary>  
394         /// 执行原始sql命令  
395         /// </summary>  
396         /// <param name="commandtext">sql命令</param>  
397         /// <param name="parameters">参数</param>  
398         /// <returns>影响的记录数</returns>  
399         public virtual ienumerable<telement> sqlquery<telement>(string sql, params object[] parameters) where telement : class, new()
400         {
401             datatable dt = this._context.database.sqlquery(sql, parameters);
402             return dt.toenumerable<telement>();
403 
404         }
405         /// <summary>
406         /// 分页查询
407         /// </summary>
408         /// <param name="pageindex">当前页</param>
409         /// <param name="pagesize">每页条数</param>
410         /// <param name="condition">lambda查询条件where</param>
411         /// <param name="ordername">排序字段 默认createtime</param>
412         /// <param name="sortorder">排序方式 asc desc,默认createtime desc</param>
413         /// <returns></returns>
414         public virtual ipagedlist<t> getlistforpaging(int pageindex, int pagesize, expression<func<t, bool>> condition = null, string ordername = null, string sortorder = null)
415         {
416             var cachekey = typeof(t).name;
417             if (pageindex < 1)
418                 pageindex = 1;
419             if (ordername == null)
420             {
421                 ordername = "createtime";
422             }
423             bool isdesc = true;
424             if(sortorder!=null&&sortorder.tolower() == "asc")
425             {
426                 isdesc = false;
427             }
428 
429             cachekey = cachekey + ".getlist";
430 
431             if(condition!=null)
432             {
433                 cachekey = cachekey + ".condition." + condition.tostring();
434             }
435 
436             list<t> resultlist = null;
437 
438             var cachedata = _cachemanager.get<list<t>>(cachekey);
439             if (cachedata != null)
440             {
441                 resultlist = cachedata.asqueryable().orderby(ordername, isdesc).tolist();
442             }
443             else
444             {
445                 if (condition == null)
446                 {
447                     resultlist = entities.tolist();
448                 }
449                 else
450                 {
451                     resultlist = entities.where(condition).tolist();
452                 }
453                 _cachemanager.set(cachekey, resultlist, 60);
454             }
455          
456             return new pagedlist<t>(resultlist, pageindex, pagesize);
457         }
458         /// <summary>
459         /// 执行sqlcommand
460         /// </summary>
461         /// <param name="sql">sql</param>
462         /// <param name="parameters">参数</param>
463         /// <returns></returns>
464         public virtual int executesqlcommand(string sql, params object[] parameters)
465         {
466             var result = this._context.database.executesqlcommand(sql, parameters);
467             return result;
468         }
469         /// <summary>
470         /// 查询列表,默认返回整个表数据
471         /// </summary>
472         /// <param name="condition">lambda查询条件where</param>
473         /// <returns></returns>
474         public virtual list<t> getlist(expression<func<t, bool>> condition = null)
475         {
476             var cachekey = typeof(t).name+ ".getlist";
477             list<t> entities = null;
478             if (condition != null)
479             {
480                 cachekey = cachekey + ".condition." + condition.tostring();
481                 entities = _cachemanager.get(cachekey,()=>this.entities.where(condition).tolist());
482             }
483             else
484             {
485                 entities = _cachemanager.get(cachekey,()=>this.entities.tolist());
486             }
487             return entities;
488         }
489         #region utilities
490 
491         /// <summary>
492         /// rollback of entity changes and return full error message
493         /// </summary>
494         /// <param name="exception">exception</param>
495         /// <returns>error message</returns>
496         protected string getfullerrortextandrollbackentitychanges(dbupdateexception exception)
497         {
498             //rollback entity changes
499             if (_context is dbcontext dbcontext)
500             {
501                 var entries = dbcontext.changetracker.entries()
502                     .where(e => e.state == entitystate.added || e.state == entitystate.modified).tolist();
503 
504                 entries.foreach(entry =>
505                 {
506                     try
507                     {
508                         entry.state = entitystate.unchanged;
509                     }
510                     catch (invalidoperationexception)
511                     {
512                         // ignored
513                     }
514                 });
515             }
516 
517             try
518             {
519                 _context.savechanges();
520                 return exception.tostring();
521             }
522             catch (exception ex)
523             {
524                 //if after the rollback of changes the context is still not saving,
525                 //return the full text of the exception that occurred when saving
526                 return ex.tostring();
527             }
528         }
529 
530         #endregion
531 
532     }
533 }
534 public static class queryableextensions
535 {
536     public static iqueryable<t> orderby<t>(this iqueryable<t> queryable, string propertyname)
537     {
538         return queryablehelper<t>.orderby(queryable, propertyname, false);
539     }
540     public static iqueryable<t> orderby<t>(this iqueryable<t> queryable, string propertyname, bool desc)
541     {
542         return queryablehelper<t>.orderby(queryable, propertyname, desc);
543     }
544     static class queryablehelper<t>
545     {
546         private static dictionary<string, lambdaexpression> cache = new dictionary<string, lambdaexpression>();
547         public static iqueryable<t> orderby(iqueryable<t> queryable, string propertyname, bool desc)
548         {
549             dynamic keyselector = getlambdaexpression(propertyname);
550             return desc ? queryable.orderbydescending(queryable, keyselector) : queryable.orderby(queryable, keyselector);
551         }
552         private static lambdaexpression getlambdaexpression(string propertyname)
553         {
554             if (cache.containskey(propertyname)) return cache[propertyname];
555             var param = expression.parameter(typeof(t));
556             var body = expression.property(param, propertyname);
557             var keyselector = expression.lambda(body, param);
558             cache[propertyname] = keyselector;
559             return keyselector;
560         }
561     }
562 }
   _cachemanager下篇我们讲到缓存管理的时候再来讲,包括依赖注入也放到下篇,今天就先到这里了!