欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

框架搭建与EF常用基类实现

程序员文章站 2023-11-15 17:01:46
前两篇简单谈了一些.Net Core的优势以及机构设计的一些思路,这一篇开始,我们将从零开始搭建架构,底层我们将采用EF来访问数据库,所以这篇我们将贴一下EF常用操作的基类。 简单介绍下一些类库将要实现的功能: Business:业务实现层 Domains:实体(Model) Service:接口 ......

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

     框架搭建与EF常用基类实现

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

           business:业务实现层

           domains:实体(model)

           service:接口

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

           easycacheing:开源缓存管理

           tools:工具类库

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

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

    框架搭建与EF常用基类实现

   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下篇我们讲到缓存管理的时候再来讲,包括依赖注入也放到下篇,今天就先到这里了!