1. 程式人生 > >一步一步學Entity Framework 4(4)

一步一步學Entity Framework 4(4)

注:本博文是"一步一步學習Entity Framework 4.x”的續篇,只講了一個概念:如何在EF中使用泛型以簡化工作.為保證延續性,本博文繼續使用前幾講的資料庫作為案例,不清楚結構的請回查前面博文的相關內容.

使用EF來進行資料查詢的確很方便,但是程式碼寫得多了以後你會發現很多工作都是重複性很強的工作,比如查詢資料並返回列表.如果是小型專案,實體類在5個以內,使用常規的查詢方法尚可忍受,但是實體類多了,老是重複同一方法,很快你就會發瘋----這不但很麻煩,也沒有必要!

怎麼辦呢,使用泛型是解決這一問題的重要途徑,通過研究,ObjectContext的CreateObjectSet方法就是解決這一問題的良方.

在MSDN裡查閱到關於ObjectContext.CreateObjectSet 方法的相關描述是這樣的:

從方法的說明來看,這是一個全能的方法,GURD樣樣精通,下面就使用它來實現泛型的資料查詢方法.

在Bussines中新建一個GeneriData靜態類,在類中編寫方法:

public static List<T> GetListOf<T>(Expression<Func<T, bool>> expression) where T:class
      {
          ProductsEntities _context = new
ProductsEntities(); return _context.CreateObjectSet<T>().Where(expression).ToList(); }

OK,就這麼兩行程式碼,解決了所有使用Lambda表示式進行查詢的問題,查詢結果返回值為任意的實體型別.

引數型別Expression<Func<T,bool>>專用於Where條件篩選的表示式,在呼叫的時候可以直接編寫Lambda表示式,由於通過CreateObjectSet<T>方法獲取了ObjectSet物件的例項,因此可以任意對該物件進行操作,另外經過測試驚喜的發現,返回的物件自動包含了所有相關類,不再需要使用Include方法再進行包含操作了(這並不奇怪,這是因為沒有將_context變數的作用域進行限定,在物件呼叫完畢以後沒有立即釋放,實際上這樣做還是有一定的效能損耗的,但是作為泛型版本的示例還真就必須這麼做,要不然在呼叫程式碼裡怎樣使用Include方法,因為ToList擴充套件方法並沒有Include擴充套件方法,鏈式語法在此不能使用).見如下示例:

在Presenter資料夾中新建一個類:GenericSearchDemo.cs.並在類中新增一個方法以顯示查詢結果,本次查詢仍然採用前面介紹的關於進行資料導航的例子,全部相關程式碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ProductEFDemo.Business;
using ProductEFDemo.Models;

namespace ProductEFDemo.Presenter
{
 public static  class GenericSearchDemo
    {
     public static void ShowProductDeatil()
     {
         var products = GenricData.GetListOf<Product>(c => (c.ProductBasePrice <= 50 && c.ProductBasePrice >= 49));
         foreach (var product in products)
         {
             Console.WriteLine(String.Format("產品名稱:{0};產品大類:{1};產品小類:{2};單位:{3};基本價格:{4};",
                 product.ProductName, product.ProductSmallType.ProductBigType.ProductBigTypeName,
                 product.ProductSmallType.ProductSmallTypeName, product.ProductUnit.ProductUnitName, product.ProductBasePrice));

            
         }
     }
    }
}

呼叫以後,輸出的效果還是一樣的:

image

除了查詢以外,還可以進行新增,修改和刪除,操作方法也很簡單,比如新增指定物件資料,就可以這樣:

public static void AddNewData<T>(T t) where T : class
      {
          using (var ctx = new ProductsEntities())
          {
              ctx.CreateObjectSet<T>().AddObject(t);
              ctx.SaveChanges();
          }
      }
到時修改我們構建一個物件型別與T一樣然後傳入函式作為引數就大功告成!

從上面的示例來看,可以說使用泛型版本的處理函式用於EF可以大大節約開發時間和程式碼數量,從而起到事半功倍的效果.美中不足的是泛型的引入又增加了解析的負擔,效能上略有損失,但這是值得的!