關於泛型介面的探討

来源:http://www.cnblogs.com/shouce/archive/2016/03/26/5321906.html
-Advertisement-
Play Games

大家在用三層架構做開發的時候,是否有使用介面,使用介面的時候是否有類似這樣的代碼: 然後每個每個表都有一個這樣的介面代碼,對比之後發現,這樣的代碼是不是很多重覆呢?那麼有什麼好的辦法可以減少這樣的重覆代碼??? 我想到的是泛型,介面同樣可以泛型,看下麵這張圖,IT_admin,IT_advs,IT_ ...


大家在用三層架構做開發的時候,是否有使用介面,使用介面的時候是否有類似這樣的代碼:

複製代碼
public interface IT_logs
    {
        #region  成員方法
        /// <summary>
        /// 得到最大ID
        /// </summary>
        int GetMaxId();
        /// <summary>
        /// 是否存在該記錄
        /// </summary>
        bool Exists(int Id);
        /// <summary>
        /// 增加一條數據
        /// </summary>
        int Add(Maticsoft.Model.T_logs model);
        /// <summary>
        /// 更新一條數據
        /// </summary>
        bool Update(Maticsoft.Model.T_logs model);
        /// <summary>
        /// 刪除一條數據
        /// </summary>
        bool Delete(int Id);
        bool DeleteList(string Idlist );
        /// <summary>
        /// 得到一個對象實體
        /// </summary>
        Maticsoft.Model.T_logs GetModel(int Id);
        Maticsoft.Model.T_logs DataRowToModel(DataRow row);
        /// <summary>
        /// 獲得數據列表
        /// </summary>
        DataSet GetList(string strWhere);
        /// <summary>
        /// 獲得前幾行數據
        /// </summary>
        DataSet GetList(int Top,string strWhere,string filedOrder);
        int GetRecordCount(string strWhere);
        DataSet GetListByPage(string strWhere, string orderby, int startIndex, int endIndex);
        /// <summary>
        /// 根據分頁獲得數據列表
        /// </summary>
        //DataSet GetList(int PageSize,int PageIndex,string strWhere);
        #endregion  成員方法
        #region  MethodEx

        #endregion  MethodEx
    } 
複製代碼

然後每個每個表都有一個這樣的介面代碼,對比之後發現,這樣的代碼是不是很多重覆呢?
那麼有什麼好的辦法可以減少這樣的重覆代碼???

我想到的是泛型,介面同樣可以泛型,看下麵這張圖,IT_admin,IT_advs,IT_artClass......,它們內部代碼幾乎一模一樣

如果我們寫這樣的一個泛型介面,那麼這一個介面就代替了上面所有的Idal介面,並且你再增加表,也不需要添加Idal的介面文件了,是不是很爽?

複製代碼
public interface IOperate<T>
    {
        bool UpdateData(T entityData);//添加、編輯
        bool Delete(int Id);//根據ID號刪除數據
        DataTable GetTable(string where, string orderBy, int pageIndex, int pageSize, out int recordCount);//返回數據表
        List<T> GetList(string sqlsStr);//返回LIST
        T GetDataById(int Id);//返回實體對象
    }
複製代碼

代碼很簡單,我就不多做解釋了,然後我們用每個DAL去實現這個介面,就可以,這樣就不需要去為每個DAL單寫一個介面了,要知道,每個DAL里的操作90%都是相同的,當然,我們也可以擴展一些其它方法出來。

其實為每個表寫DAL中,也是有功能可以抽象出來的,比如:刪除,判斷ID號是否存在,每個DAL所操作的表名,和表的主鍵,還有資料庫操作對象,這些內容其實也可以抽象出來,所以我想到建立一個DALBASE的抽象類,提供一些虛方法,如果哪個DAL不一樣,那就重寫虛方法就可以了。所以有了下麵這個類

複製代碼
public abstract class DalBase
    {
        protected string TableName { set; get; }
        protected string PkField { set; get; }

        protected Database da = DatabaseFactory.CreateDatabase();
        /// <summary>
        /// 刪除
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public virtual bool Delete(int Id)
        {
            var sqlStr = "delete from {0} where {1}=@Id";
            sqlStr = string.Format(sqlStr, this.TableName, this.PkField);
            var command = da.GetSqlStringCommand(sqlStr);
            da.AddInParameter(command, "@Id", DbType.Int32, Id);
            return da.ExecuteNonQuery(command) > 0;
        }
       /// <summary>
       /// 判斷是否存在
       /// </summary>
       /// <param name="Id"></param>
       /// <returns></returns>
        public virtual bool IsExists(int Id)
        {
            var sqlStr = "select count(*) from @TableName where @PkField=@Id";
            var command = da.GetSqlStringCommand(sqlStr);
            da.AddInParameter(command, "@TableName", DbType.String, this.TableName);
            da.AddInParameter(command, "@PkField", DbType.String, this.PkField);
            da.AddInParameter(command, "@Id", DbType.Int32, Id);
            var obj = da.ExecuteScalar(command);
            if (obj != null && !Convert.IsDBNull(obj))
            {
                return int.Parse(obj.ToString()) > 0;
            }
            return false;
        }
       
    }
複製代碼

那麼DAL類的代碼應該是怎麼樣?

複製代碼
public class AdminDal : DalBase, IOperate<AdminEntity>
    {

        public AdminDal()
        {
            this.TableName = "T_Admin";
            this.PkField = "Id";
        }
        /// <summary>
        /// 添加,編輯
        /// </summary>
        /// <param name="entityData"></param>
        /// <returns></returns>
        public bool UpdateData(AdminEntity entityData)
        {
            var sqlStr = string.Empty;
            DbCommand command;
            if (entityData.Id == 0)//添加
            {
                sqlStr = @"insert into {0}(UserName,UserPwd,Flag,PostTime) values(@UserName,@UserPwd,@Flag,@PostTime)";
                sqlStr = string.Format(sqlStr, this.TableName);
                command = da.GetSqlStringCommand(sqlStr);
            }
            else//編輯
            {
                sqlStr = @"update {0} set UserPwd=@UserPwd,Flag=@Flag,PostTime=@PostTime where {1}=@Id";
                sqlStr = string.Format(sqlStr, this.TableName, this.PkField);
                command = da.GetSqlStringCommand(sqlStr);
                da.AddInParameter(command, "@Id", DbType.Int32, entityData.Id);
            }
            da.AddInParameter(command, "@UserName", DbType.String, entityData.UserName);
            da.AddInParameter(command, "@UserPwd", DbType.String, entityData.UserPwd);
            da.AddInParameter(command, "@Flag", DbType.String, entityData.Flag);
            da.AddInParameter(command, "@PostTime", DbType.DateTime, entityData.PostTime);
            return da.ExecuteNonQuery(command) > 0;
        }

        public List<AdminEntity> GetList(string sqlStr)
        {
            var list = new List<AdminEntity>();
            var command = da.GetSqlStringCommand(sqlStr);
            var dt = da.ExecuteDataSet(command).Tables[0];
            if (dt != null && dt.Rows.Count > 0)
            {
                foreach (DataRow dr in dt.Rows)
                {
                    var entity = new AdminEntity()
                    {
                        Id = int.Parse(dr["Id"].ToString()),
                        UserName = dr["UserName"].ToString(),
                        UserPwd = dr["UserPwd"].ToString(),
                        Flag = dr["Flag"].ToString(),
                        PostTime = DateTime.Parse(dr["PostTime"].ToString())
                    };
                    list.Add(entity);
                }
            }
            return list;
        }
        //分頁查詢,需要SQL2005 以上的版本支持
        /*private const string DefaultSqlStr = @"
        SELECT * FROM (
            SELECT row_number() OVER({0}) as ROW_NUMBER,* FROM 
            ( 
                SELECT *  FROM T_admin
                {1}
            ) as a
        ) as b WHERE ROW_NUMBER > {2} AND ROW_NUMBER <= {3}";
         */
        //分頁查詢
        private const string DefaultSqlStr = @"select top {0} * from {1} where {2} not in (select top {3} {4} from {5} where 1=1 {6} {7}) {8} {9} ";
        private const string DefaultSqlCount = @"select count(*)  FROM {0} where 1=1 {1}";
        public DataTable GetTable(string where, string orderBy, int pageIndex, int pageSize, out int recordCount)
        {
            var sql = String.Format(DefaultSqlCount, this.TableName, where);
            var obj = da.ExecuteScalar(CommandType.Text, sql);
            recordCount = 0;
            if (obj != null && !Convert.IsDBNull(obj))
            {
                recordCount = int.Parse(obj.ToString());//記錄條數
            }
            pageIndex = pageIndex > 0 ? pageIndex : 1;//最小為1
            if (string.IsNullOrEmpty(orderBy))
            {
                orderBy = " order by " + this.PkField + " Desc";
            }
            sql = String.Format(DefaultSqlStr, pageSize, this.TableName, this.PkField, (pageIndex - 1) * pageSize, this.PkField, this.TableName, where, orderBy, where, orderBy);
            return da.ExecuteDataSet(CommandType.Text, sql).Tables[0];
        }
        public AdminEntity GetDataById(int Id)
        {
            var sqlStr = "select * from {0} where {1}=@Id";
            sqlStr = string.Format(sqlStr, this.TableName, this.PkField);
            var command = da.GetSqlStringCommand(sqlStr);
            da.AddInParameter(command, "@Id", DbType.Int32, Id);
            var dt = da.ExecuteDataSet(command).Tables[0];
            if (dt != null && dt.Rows.Count > 0)
            {
                var dr = dt.Rows[0];
                var entity = new AdminEntity()

                {
                    Id = int.Parse(dr["Id"].ToString()),
                    UserName = dr["UserName"].ToString(),
                    UserPwd = dr["UserPwd"].ToString(),
                    Flag = dr["Flag"].ToString(),
                    PostTime = DateTime.Parse(dr["PostTime"].ToString())
                };
                return entity;
            }
            return null;
        }


    }
複製代碼

DAL類繼承了DalBase,並實現了泛型介面。。
最後我們要完成Bll類:

複製代碼
public class AdminBll
    {
        private static readonly IOperate<AdminEntity> iDal = new AdminDal();
        public static bool UpdateData(AdminEntity entity)
        {
            return iDal.UpdateData(entity);
        }
        public static bool Delete(int Id)
        {
            return iDal.Delete(Id);
        }
        public static List<AdminEntity> GetList(string sqlStr)
        {
            return iDal.GetList(sqlStr);
        }
        public static DataTable GetTable(string where, string orderBy, int pageIndex, int pageSize, out int recordCount)
        {
            return iDal.GetTable(where, orderBy, pageIndex, pageSize, out recordCount);
        }
        public static AdminEntity GetDataById(int id)
        {
            return iDal.GetDataById(id);
        }

    }
複製代碼


那麼,當我們需要調用方法的時候,代碼是怎麼樣的?

複製代碼
var adminEntity = new AdminEntity()
            {
                UserName = "admin888",
                UserPwd = "admin888",
                Flag = "0",
                PostTime = DateTime.Now
            };
            AdminBll.UpdateData(adminEntity);
複製代碼

這樣就實現了一個添加的操作。。。

其實我自己並不確定這樣去使用泛型介面是否合理,歡迎大家噴,但請告訴我原因,因為我自認自己是菜鳥,需要學習。。。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 轉自:http://yangrong.blog.51cto.com/6945369/1288072 目錄 1、樹狀目錄結構圖 2、/目錄 3、/etc/目錄 4、/usr/目錄 5、/var/目錄 6、/proc/目錄 7、/dev/目錄 該文章主要來自於網路進行整理。 目錄結構參考地址: http ...
  • 安裝ubuntu後,出現無法識別顯示器,從而造成無法設置高解析度。 界面顯示似老年機般,5.3的視力+強迫症,臣妾的內心是十分拒絕的,搗鼓了半天終於搞定,這裡記錄下方法。 (一)使用xrandr命令,查看當前顯示器顯示配置 lilip@lilip:~$ xrandr Screen 0: minimu ...
  • 回車 代碼:CR ASCII碼:\ r ,十六進位,0x0d,回車的作用只是移動游標至該行的起始位置; 換行 代碼:LF ASCII碼:\ n ,十六進位,0x0a,換行至下一行行首起始位置; ...
  • vim /etc/init.d/nginx 1 #!/bin/bash 2 # nginx Startup script for the Nginx HTTP Server 3 # it is v.0.0.2 version. 4 # chkconfig: 2345 30 30 5 # descri ...
  • 在Nginx的插件模塊中有一個模塊stub_status可以監控Nginx的一些狀態信息,預設安裝可能沒有這個模塊,手動編譯的時候加一下即可。 1. 模塊安裝 先使用命令查看是否已經安裝這個模塊: 如果已經安裝,會在顯示的信息中包含 --with-http_stub_status_module信息。 ...
  • 51 Windows 無法找到網路路徑。請確認網路路徑正確並且目標電腦不忙或已關閉。如果 Windows 仍然無法找到網路路徑,請與網路管理員聯繫。 52 由於網路上有重名,沒有連接。請到“控制面板”中的“系統”更改電腦名,然後重試。 53 找不到網路路徑。 54 網路很忙。 55 指定的網路資 ...
  • ID 類型 來 源 代 表 的 意 義 舉 例 解 釋 ...
  • 一、進程/線程 進程:系統進行資源分配和調度的一個獨立單位。(存資源) 線程:CPU調度和分派的基本單位。(執行) 一個進程可以有多個線程,一個線程可與同屬一個進程的其他線程共用進程所擁有的全部資源。 場景:超市。 /// <summary> /// 單線程 /// </summary> /// < ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...