.Net 自己寫個簡單的 半 ORM (練手)


   ORM 大家都知道, .Net 是EF  還有一些其他的ORM  從JAVA 中移植過來的 有 , 大神自己寫的也有 

   不管ORM 提供什么附加的 亂七八糟的功能  

   但是 最主要的 還是 關系映射 的事情。

   我自己一直在使用ORMDapper 這個很小的ORM  第一次看到這個ORM  是通過一個帖子中 有人搞了個常見ORM 效率排行榜 ,自己也試了試  然后就看上 ORMDapper 這個了

   這是把輕量級發揮到極致了! 只有一個 96KB 的 一個Class 文件。其中還有很多是空格和注釋信息。 

   

    最近在學習研究JAVA   覺得JAVA 比.NET  有趣點。  也為了 以后 .NET 不行了  還能弄JAVA  

 

    直接上代碼:

 

      

        private static string ConnectionString = "**";
         
        /// <summary>
        ///  更新數據   沒有sql參數就直接執行  
        /// </summary>
        /// <param name="sql"> 需要執行的 sql </param>
        /// <param name="o">傳遞的實體類對象 要求該類中字段必須和 sql參數名稱一致 不區分大小寫 </param>
        /// <returns></returns>
        public static int UpdateModel(string sql, object o)
        {
            var s = sql.Split('@');
            return Update(sql, s.Length == 1 ? null : GetSqlParameters(o, s));
        }


        /// <summary>
        ///  查詢數據
        /// </summary>
        /// <typeparam name="T">映射的實體類</typeparam>
        /// <param name="sql">執行的SQL語句</param>
        /// <param name="o">傳遞的實體類對象 要求該類中字段必須和 sql參數名稱一致 不區分大小寫 </param>
        /// <returns></returns>
        public static List<T> SeleteModel<T>(string sql, object o) where T : class, new()
        {
            var s = sql.Split('@');
            return Select<T>(sql, s.Length == 1 ? null : GetSqlParameters(o, s));
        }

        /// <summary>
        /// 動態創建SqlParameter 對象
        /// </summary>
        /// <param name="o">傳遞的實體類對象 要求該類中字段必須和 sql參數名稱一致 不區分大小寫 </param>
        /// <param name="s">切割后的SQL 語句</param>
        /// <returns></returns>
        private static SqlParameter[] GetSqlParameters(object o, string[] s)
        {
            s = s.Select(c => c.Split(' ')[0].Trim()).ToArray(); 

            Type t = o.GetType();
            if (t == typeof(object))
                throw new Exception("UpdateModel  傳遞的類型是OBJECT 類型");
            // 反射 讀取字段 驗證是否是 SQL 中的參數
            var tlist =
                t.GetFields(BindingFlags.Public | BindingFlags.Instance)
                    .Where(c => c.GetValue(o) != null & s.FirstOrDefault(a => a.ToLower() == c.Name.ToLower()) != null)
                    .ToList();
            // 判斷得到的數據 是否和 需要的數據 數量一致
            if (tlist.Count() != s.Count() - 1)
                throw new Exception("傳遞的實體中有值參數 和 sql 中需要的 數量不相等");

            SqlParameter[] sp = new SqlParameter[tlist.Count()];
            for (int i = 0; i < s.Length - 1; i++)
            {
                sp[i] = new SqlParameter(s[i + 1].Trim(), tlist.FirstOrDefault(c => c.Name.ToLower() == s[i + 1].ToLower()).GetValue(o));
            }
            return sp;
        }

        private static List<T> SeleteModel<T>(SqlDataReader data) where T : class, new()
        {
            // 獲取列 個數
            int iFieldCount = data.FieldCount;
            List<T> list = new List<T>();
            while (data.Read())
            {
                T tType = new T();
                for (int i = 0; i < iFieldCount; i++)
                {
                    // 反射注入字段值
                    string dataName = data.GetName(i);
                    FieldInfo fie = tType.GetType().GetField(dataName);
                    if (fie == null)
                        continue;
                    fie.SetValue(tType, data[dataName]);
                }
                list.Add(tType);
            }
            return list;
        }


        private static List<T> Select<T>(string sql, SqlParameter[] sp) where T : class, new()
        {
            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                using (SqlCommand com = new SqlCommand(sql, conn))
                {
                    conn.Open();
                    if (sp != null)
                        com.Parameters.AddRange(sp);
                    return SeleteModel<T>(com.ExecuteReader());
                }
            }
        }

        private static int Update(string sql, SqlParameter[] sp)
        {
            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                using (SqlCommand com = new SqlCommand(sql, conn))
                {
                    conn.Open();
                    if (sp != null) 
                        com.Parameters.AddRange(sp); 
                    return com.ExecuteNonQuery();
                }
            }
        }

   調用示例:

  

 public class TestCalss
    {
        public static void Main()
        {
            string sql = @"SELECT TOP 1000 [ID]
                           ,[ExpressID]
                          ,[OrderID]
                          ,[MailCode] 
                          ,[SendXML]
                          ,[SendFlag]
                          ,[SendCount] 
                      FROM [SendStateTest]  where id=@id  and SendXML=@SendXML  ";

            string sql2 = @"update [DangDang_SendStateTest] set  SendXML='0000' where id=@id     "; 

            int i = AdoConnection.UpdateModel(sql2, new Na() { ID = 1 });

            List<Na> a = AdoConnection.SeleteModel<Na>(sql, new Na() { ID = 1, SendXML = "0000" });
            Console.WriteLine(a); 
        }

        public class Na
        { 
            public int ID; 
            public string ExpressID; 
            public string OrderID; 
            public string MailCode;  
            public string SendXML; 
            public int SendFlag; 
            public int SendCount;

        } 
    }

  

     只是提供一種自己做一個簡單的  三分之一 “ORM” 的  方式   (沒有連接池  還得寫Sql   )  

     說實話,自己弄的在好,也不如 網上大家都在用的 “ORM” 框架

     可以在這個簡單的 “ORM” 上經行加工 拓展,  比如 支持存儲過程  不限定數據庫  SQL 語句 分類    等等  

     有興趣的朋友可以自己做做 ,我就不弄了。

     如果你使用過多種ORM 你就會發現 越是功能全 越是強大的ORM 效率就越低    因為不管是哪個ORM 最后還是對JDBC/ADO.NET 的加工封裝 。 

     EF 效率是低  但是 他的 是 我弄過的一下ORM框架中 是功能最全 除去效率外 其他都很強大。

 

     


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM