[.NET] MongoDB 泛型<T>新增、讀取、更新、刪除 (CRUD) 操作

介紹 MongoDB 上使用泛型來操作 CRUD 方法。

前言


首先一定要先說明一下不是來騙稿費的 XD,上一篇 文中已經介紹了 MongoDB 的 CRUD 方法,這一篇就來將上一篇的程式碼做一點修改,調整成使用泛型的方法來時做 CRUD 以提高程式碼的重用性。

 

在上一篇文章中的 ProductDao 類別中,因為在類別中寫死了只能去使用 Products Collection,在這種模式下如果多了一個 OrderDao 就需要撰寫同樣的程式碼,而如果而外撰寫了 OrderDao 類別後卻會發現此兩個 Dao 程式碼重複性很高,這時我們就必須適當的重構一下,將 Dao 的 CRUD 方法使用泛型來處理,如此則能夠提升程式碼的重用性。

 

套用泛型<T> CRUD 方法


首先沿用上次一個網站程式碼,加入一個新的 MongoDbDao 類別,將 GetAll()、GetById()、Insert()、Update()、DeleteById() 方法都先複製進來。

 

Step 1

先修改 MongoDbDao 類別的建構子,將原本在建構子就指定 Collection 的程式碼拿掉,並且加入一個 UseCollection(string collectionName) 方法,用來指定之後要使用的 Collection Name。再將 GetDatabase() 方法寫死的 test 改成由外部傳入,如下。


private MongoClient _mongoClient;
private MongoServer _mongoServer;
private MongoDatabase _mongoDatabase;
private string _useCollectionName;

public MongoDbDao(string databaseName)
{
    // MongoDB 連線字串
    string connectionString = 
        ConfigurationManager.ConnectionStrings["MongoDbConnectionString"].ConnectionString;
    // 產生 MongoClient 物件
    _mongoClient = new MongoClient(connectionString);
    // 取得 MongoServer 物件
    _mongoServer = _mongoClient.GetServer();
    // 取得 MongoDatabase 物件
    _mongoDatabase = _mongoServer.GetDatabase(databaseName);
}

public void UseCollection(string collectionName)
{
    if (string.IsNullOrEmpty(collectionName))
        throw new Exception("collectionName can't empty or null.");

    _useCollectionName = collectionName;
}

 

Step 2

增加一個新 GetCollection<T>() 私有方法,用來包裝由 MongoDatabase 類別呼叫  GetCollection<T>(string collectionName) 時的重複程式碼,在此 Collection Name 需要由 _useCollectionName 欄位指定,如下。


private MongoCollection<T> GetCollection<T>()
{
    return _mongoDatabase.GetCollection(_useCollectionName);
}

 

Step 3

修改原本的 CRUD 方法,如下


public IQueryable<T> GetAll<T>() where T : class
{
    var collection = GetCollection<T>();
    return collection.AsQueryable<T>();
}

public T GetById<T>(Expression<Func<T, bool>> expression) where T : class
{
    var query = Query<T>.Where(expression);
    var document = GetCollection<T>().FindOne(query);
    return document;
}

public bool Insert<T>(T entity) where T : class
{
    return GetCollection<T>().Insert(entity).Ok;
}

public bool Update<T>(T entity) where T : class
{
    return GetCollection<T>().Save(entity).Ok;
}

public bool Delete<T>(Expression<Func<T, bool>> expression) where T : class
{
    var query = Query<T>.Where(expression);
    return GetCollection<T>().Remove(query).Ok;
}

 

在以上 CRUD 方法中各別使用了 T 泛型型別,並且 GetById() 與 Delete() 方法的傳入引數調整成傳入 Linq.Expression<Func<T,bool>> 參數,藉由呼叫端自行建構泛型 Expression Lambda 條件,以上的修改完成後,基本上這個 MongoDbDao 類別就可以提供給多種 Entity 使用了。

 

在 Page 頁面上,呼叫的方式則改為以下程式碼。


private MongoDbDao _mongoDbDao;
private Random _random = new Random();

protected void Page_Load(object sender, EventArgs e)
{
    _mongoDbDao = new MongoDbDao("test");
    _mongoDbDao.UseCollection("Products");
}

// 新增
_mongoDbDao.Insert<Product>(product);
// 更新
_mongoDbDao.Update<Product>(product);
// 刪除
Expression<Func<Product, bool>> expression = p => p.ID == id;
_mongoDbDao.Delete<Product>(expression);
// 查詢
_mongoDbDao.GetAll<Product>();
// 單筆查詢
Expression<Func<Product, bool>> expression = p => p.ID == id;
_mongoDbDao.GetById<Product>(expression);

 

也就是在一開始呼叫 UseCollection() 方法指定名稱,如需要更換時再呼叫一次 UseCollection() 方法即可,而各自 CRUD 方法要多指定 Entity 的型別,但是當有新的 Entity 出現時就不用額外去撰寫 Dao 方法,只需呼叫 MongoDbDao 的方法並換掉 Entity 型別即可,以上就是基本使用泛型的操作方式。

 

範例程式碼


TMongoDB_02.rar

 

 


以上文章敘述如有錯誤及觀念不正確,請不吝嗇指教
如有侵權內容也請您與我反應~謝謝您 :)