基於Entity Framework的自定義分頁,增刪改的通用實現

来源:http://www.cnblogs.com/jinweijie/archive/2017/07/24/entity_framework_generic_repository.html
-Advertisement-
Play Games

一個基於Entity Framework的自定義分頁,增刪改的通用實現,同時包含Entity的生成,Specification模式,Unit of Work實現。 ...


簡介

之前寫個一個基於Dapper的分頁實現,現在再來寫一個基於Entity Framework的分頁實現,以及增刪改的通用實現。

代碼

還是先上代碼:https://github.com/jinweijie/EF.GenericRepository

如何運行示例

還是像先前一樣:

1. 先Clone下代碼,在Database裡面解壓縮Database.7z

2. Attach到Sql Server LocalDB上。如果你用的不是Sql Server的LocalDB,你需要更改App.Config里的連接字元串。

3. Ctrl + F5,運行示常式序。

Repository 基類 - 查詢

Common\AbstractRepository.cs 是Repository的基類,實現了增刪改查的一些方法,例如:

public virtual Tuple<IEnumerable<T>, int> Find(Expression<Func<T, bool>> criteria
            , int pageIndex
            , int pageSize
            , string[] asc
            , string[] desc
            , params Expression<Func<T, object>>[] includeProperties)

這個方法是AbstractRepository查詢方法中的一個,用於自定義分頁查詢,其中criteria 為一個表達式,作為查詢的條件,參數pageIndex, pageSize, asc, desc為分頁相關參數;

關於多表(關聯表):

includeProperties為在多表時候,Join相關聯的表。因為EF預設是Lazy Loading,相關聯的表預設不是立即載入的,所以有時候如果寫代碼不小心,在for迴圈里就有可能會迴圈查詢n個字表。用來includeProperties參數,就可以在查詢時候join關聯表。

Repository 基類 - 增刪改

AbstractRepository已經用泛型實現了增刪改方法:

  • public virtual T Create(T entity)
  • public virtual T Update(T entity)
  • public virtual T CreateOrUpdate(T entity)
  • public virtual void Delete(TId id)

 另外,關於transaction的實現,我使用了Unit of Work模式,多個Repository共用一個DBContext,關於UOW,請在Common\UnitOfWork.cs里找到。

 調用UOW的時候,基本類似於這樣:

var uow = new EFUnitOfWork();
var repo = uow.GetLogRepository();

repo.Create(new Log
{
    LevelId = 1,
    Thread = "",
    Location = "Manual Creation",
    Message = "This is manually created log.",
    CreateTime = DateTimeOffset.Now,
    Date = DateTime.Now
});

uow.Commit();

從UnitOfWork里得到一個或多個Repository,共用DBContext,做增刪改操作,最後uow統一SaveChanges。

 Repository的派生類

由於已經有了AbstractRepository,實現了增刪改查的很多方法,所以派生類,例如示例項目里的LogRepository基本就可以變得很簡單,主要實現一些特定的業務邏輯,在示例項目里,因為沒有特殊的業務邏輯,所以會很簡單:

    public class LogRepository : AbstractRepository<Log, int>
    {
        public LogRepository(EFContext context)
            : base(context)
        {
        }
    }

關於Entity的生成

本人比較喜歡Database First 實現,先設計資料庫,然後用edmx reverse engineering,生成POCO。可以參考Entity目錄下的相關文件。

當然,如果你喜歡Code First,同樣沒有問題,仍然適用本文的實現。

使用Logging日誌追蹤EF SQL

在使用Entity Framework的時候,最好關心一下EF所生成的SQL,這樣可以在開發階段發現一些潛在的性能問題,避免在生產環境焦頭爛額:)

在Common\EFContext.cs 里,有一個配置項EnableTraceSql,如果為true,那麼所以EF生成的SQL將會被nlog記錄下來。我將nlog的日誌配置到了資料庫。也就是說,在你運行示例項目時,每次查詢,都會增加新的日誌記錄,內容為查詢時生成的SQL:

 Specification Pattern

在查詢方法里,有個重載是接受一個ISpecification示例,這樣的實現可以有效的控制業務邏輯,對於寫給被其他人調用的介面來說,可以明確的確定查詢參數,例如:

    public class LogSearchSpecification : ISpecification<Log>
    {
        public string LevelName { get; set; }
        public string Message { get; set; }
        public Expression<Func<Log, bool>> ToExpression()
        {
            return log => (log.Level.Name == LevelName || LevelName == "") &&
                          (log.Message.Contains(Message) || Message == "");
        }

        public bool IsSatisfiedBy(Log entity)
        {
            return (entity.Level.Name == LevelName || LevelName == "") &&
                   (entity.Message.Contains(Message) || Message == "");
        }
    }

那麼,調用這個查詢方法的代碼就可以明確知道,我的查詢條件為LevelName和Message,至於LevelName是等於以及Message為Like則是在LogSearchSpeficiation里實現,做到很好的封裝。

最後

這套實現是幾年來平時慢慢積累的,是經過實踐的,所以應該可以作為一定的參考,當然,在具體的項目里,可以用一些DI去拿到Repository等等,不在本文討論範圍,大家可以自由發揮,希望對大家可以有所幫助,謝謝。


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

-Advertisement-
Play Games
更多相關文章
  • 為wget使用代理,可以直接修改/etc/wgetrc,也可以在主文件夾下新建.wgetrc,並編輯相應內容,本文采用後者。 直接往~/.wgetrc(自行創建此文件)添加如下內容: https_proxy = http://127.0.0.1:8087/http_proxy = http://12 ...
  • 在使用電腦時,其最大支持的記憶體是由 操作系統 和 硬體 兩方面決定的。 先說一下硬體方面的因素,在電腦中 CPU的地址匯流排數目 決定了CPU 的 定址 範圍,這種由地址匯流排對應的地址稱作為物理地址。假如CPU有32根地址匯流排(一般情況下32位的CPU的地址匯流排是32位,也有部分32位的CPU地址 ...
  • 本文為命令rsync的man文檔翻譯,幾乎所有的選項都翻譯了,另外關於篩選規則部分只翻譯了一部分。由於原文很多地方都比較啰嗦,所以譯文中有些內容可能容易讓國人疑惑,所以我個人在某些地方加上了註釋。若有錯誤之處,盼請指出。 回到系列文章大綱:http://www.cnblogs.com/f-ck-ne ...
  • 本篇為rsync官方推薦文章How Rsync Works的翻譯,主要內容是Rsync術語說明和簡單版的rsync工作原理。本篇沒有通篇都進行翻譯,前言直接跳過了,但為了文章的完整性,前言部分的原文還是保留了。 How Rsync WorksA Practical Overview Foreword ...
  • 1. 首先進入單用戶模式: 1). ubuntu : 上述情況可以在grub界面選擇第二項修複,但沒有grub可以參考: 1、重啟ubuntu,隨即長按shirft進入grub菜單; 2、選擇recovery mode,按"e"鍵進入編輯頁面;如下: 非恢復模式為: 3、將ro recovery n ...
  • 1.先創建一個文件夾用以存放鏡像 2.運行vmware,點擊創建新的虛擬機 3.選擇典型安裝 4. 選擇稍後安裝操作系統 5.選擇客戶機操作系統為Linux,版本為CentOS 64位 6. 選擇一開始創建的用以存放鏡像的文件,並給虛擬機命名 7.選擇磁碟大小,選擇預設20G即可 8.點擊完成 9. ...
  • 做為程式員的我們,經常會要用到文件的上傳和下載功能。到了需要用的時候,各種查資料。有木有..有木有...。為了方便下次使用,這裡來做個總結和備忘。 利用表單實現文件上傳 最原始、最簡單、最粗暴的文件上傳。 前端代碼: 【註意】 1、需要post提交 2、enctype="multipart/form ...
  • 背水一戰 Windows 10 之 控制項(媒體類): 通過處理 Pointer 相關事件實現一個簡單的塗鴉板, InkCanvas 基礎知識 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...