1. 程式人生 > 其它 >ABP實現EF執行SQL(增刪改查)解決方案

ABP實現EF執行SQL(增刪改查)解決方案

https://www.cnblogs.com/Jinfeng1213/p/11321414.html

前言

  一般情況下,使用EF中的語法可以幫助我們完成絕大部分業務,但是也有特殊的情況需要直接執行的Sql語句。比如,我們的業務過於複雜繁瑣,或是有些業務使用EF操作時比較複雜,但是使用的Sql時會很簡單等,這時就有了以下需求了。

具體實現

  1,首先我們需要定義一個介面類:ISqlExecuter(名字看你心情了)

 1 public interface ISqlExecuter
 2     {
 3         /// <summary>
 4         /// 執行給定的命令
 5         /// </summary>
 6         /// <param name="sql">命令字串</param>
 7         /// <param name="parameters">要應用於命令字串的引數</param>
 8         /// <returns>執行命令後由資料庫返回的結果</returns>
 9         int Execute(string sql);
10 
11         /// <summary>
12         /// 傳入查詢sql,返回List<T>陣列
13         /// </summary>
14         /// <param name="sql"></param>
15         /// <returns></returns>
16         Task<List<T>> SqlQuery<T>(string sql) where T : class, new();
17     }

  2,定義實現類:SqlExecuter(名字看你心情了)

 1  public class SqlExecuter : ISqlExecuter, ITransientDependency
 2     {
 3         private IDbContextProvider<OADbContext> _dbContextProvider = null;
 4 
 5         public SqlExecuter(IDbContextProvider<OADbContext> dbContextProvider)
 6         {
 7             _dbContextProvider = dbContextProvider;//IocManager.Instance.Resolve<IDbContextProvider<OADbContext>>();
 8         }
 9 
10         /// <summary>
11         /// 執行給定的命令
12         /// </summary>
13         /// <param name="sql">命令字串</param>
14         /// <param name="parameters">要應用於命令字串的引數</param>
15         /// <returns>執行命令後由資料庫返回的結果</returns>
16         public int Execute(string sql)
17         {
18             return _dbContextProvider.GetDbContext().Database.ExecuteSqlCommand(new RawSqlString(sql));
19         }
20 
21         /// <summary>
22         /// 傳入查詢sql,返回List<T>陣列
23         /// </summary>
24         /// <param name="sql"></param>
25         /// <returns></returns>
26         public async Task<List<T>> SqlQuery<T>(string sql) where T : class, new()
27         {
28             return await Task.Run(() =>
29             {
30                 var db = _dbContextProvider.GetDbContext().Database;
31                 var conn = db.GetDbConnection();
32                 if (conn.State != ConnectionState.Open)
33                     conn.Open();
34 
35                 var result = new List<T>();
36 
37                 try
38                 {
39                     RelationalDataReader query = null;
40 
41                     using (db.GetService<IConcurrencyDetector>().EnterCriticalSection())
42                     {
43                         var rawSqlCommand = db.GetService<IRawSqlCommandBuilder>().Build(sql);
44 
45                         query = rawSqlCommand.ExecuteReader(db.GetService<IRelationalConnection>());
46                     }
47 
48                     //獲取DbDataReader
49                     var dr = query.DbDataReader;
50 
51                     var properties = typeof(T).GetProperties().ToList();
52 
53                     while (dr.Read())
54                     {
55                         var obj = new T();
56                         foreach (var property in properties)
57                         {
58                             //獲取該欄位明的列序號,從0開始
59                             var id = dr.GetOrdinal(property.Name.ToLower());
60 
61                             if (!dr.IsDBNull(id))
62                             {
63                                 if (dr.GetValue(id) != DBNull.Value)
64                                 {
65                                     property.SetValue(obj, dr.GetValue(id));
66                                 }
67                             }
68                         }
69 
70                         result.Add(obj);
71                     }
72 
73                     //關閉DbDataReader
74                     dr.Close();
75                 }
76                 catch (Exception e)
77                 {
78                     throw new UserFriendlyException(e.Message);
79                 }
80 
81                 return result;
82             });
83         }
84     }

注意:

  引用ITransientDependency介面是為了ABP的自動註冊到容器。

使用方式

  1,注入例項:

  2,呼叫