程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 基於C#的MongoDB數據庫開發應用(3)--MongoDB數據庫的C#開發之異步接口,

基於C#的MongoDB數據庫開發應用(3)--MongoDB數據庫的C#開發之異步接口,

編輯:C#入門知識

基於C#的MongoDB數據庫開發應用(3)--MongoDB數據庫的C#開發之異步接口,


在前面的系列博客中,我曾經介紹過,MongoDB數據庫的C#驅動已經全面支持異步的處理接口,並且接口的定義幾乎是重寫了。本篇主要介紹MongoDB數據庫的C#驅動的最新接口使用,介紹基於新接口如何實現基礎的增刪改查及分頁等處理,以及如何利用異步接口實現基類相關的異步操作。

MongoDB數據庫驅動在2.2版本(或者是從2.0開始)好像完全改寫了API的接口,因此目前這個版本同時支持兩個版本的API處理,一個是基於MongoDatabase的對象接口,一個是IMongoDatabase的對象接口,前者中規中矩,和我們使用Shell裡面的命令名稱差不多,後者IMongoDatabase的接口是基於異步的,基本上和前者差別很大,而且接口都提供了異步的處理操作。

1、MongoDB數據庫C#驅動的新接口

新接口也還是基於數據庫,集合,文檔這樣的處理概念進行封裝,只是它們的接口不再一樣了,我們還是按照前面的做法,定義一個數據庫訪問的基類,對MongoDB數據庫的相關操作封裝在基類裡面,方便使用,同時基類利用泛型對象,實現更強類型的約束及支持,如基類BaseDAL的定義如下所示。

    /// <summary>
    /// 數據訪問層的基類
    /// </summary>
    public partial class BaseDAL<T> where T : BaseEntity, new()

利用泛型的方式,把數據訪問層的接口提出來,並引入了數據訪問層的基類進行實現和重用接口,如下所示。

基於新接口,如獲取數據庫對象的操作,則利用了IMongoDatabase的接口了,如下所示。

            var client = new MongoClient(connectionString);
            var database = client.GetDatabase(new MongoUrl(connectionString).DatabaseName);

相對以前的常規接口,MongoClient對象已經沒有了GetServer的接口了。如果對創建數據庫對象的操作做更好的封裝,可以利用配置文件進行指定的話,那麼方法可以封裝如下所示。

        /// <summary>
        /// 根據數據庫配置信息創建MongoDatabase對象,如果不指定配置信息,則從默認信息創建
        /// </summary>
        /// <param name="databaseName">數據庫名稱,默認空為local</param>
        /// <returns></returns>
        protected virtual IMongoDatabase CreateDatabase()
        {
            string connectionString = null;
            if (!string.IsNullOrEmpty(dbConfigName))
            {
                //從配置文件中獲取對應的連接信息
                connectionString = ConfigurationManager.ConnectionStrings[dbConfigName].ConnectionString;                
            }
            else
            {
                connectionString = defaultConnectionString;
            }

            var client = new MongoClient(connectionString);
            var database = client.GetDatabase(new MongoUrl(connectionString).DatabaseName);

            return database;
        }

根據IMongoDatabase 接口,那麼其獲取集合對象的操作如下所示,它使用了另外一個定義IMongoCollection了。

        /// <summary>
        /// 獲取操作對象的IMongoCollection集合,強類型對象集合
        /// </summary>
        /// <returns></returns>
        public virtual IMongoCollection<T> GetCollection()
        {
            var database = CreateDatabase();
            return database.GetCollection<T>(this.entitysName);
        }

2、查詢單個對象實現封裝處理

基於新接口的查詢處理,已經沒有FindOne的方法定義了,只是使用了Find的方法,而且也沒有了Query的對象可以作為條件進行處理,而是采用了新的定義對象FilterDefinition,例如對於根據ID查詢單個對象,接口的實現如下所示。

        /// <summary>
        /// 查詢數據庫,檢查是否存在指定ID的對象
        /// </summary>
        /// <param name="key">對象的ID值</param>
        /// <returns>存在則返回指定的對象,否則返回Null</returns>
        public virtual T FindByID(string id)
        {
            ArgumentValidation.CheckForEmptyString(id, "傳入的對象id為空");

            IMongoCollection<T> collection = GetCollection();
            return collection.Find(s=> s.Id == id).FirstOrDefault();
        }

對於利用FilterDefinition進行查詢的操作,如下所示。

        /// <summary>
        /// 根據條件查詢數據庫,如果存在返回第一個對象
        /// </summary>
        /// <param name="filter">條件表達式</param>
        /// <returns>存在則返回指定的第一個對象,否則返回默認值</returns>
        public virtual T FindSingle(FilterDefinition<T> filter)
        {
            IMongoCollection<T> collection = GetCollection();
            return collection.Find(filter).FirstOrDefault();
        } 

我們可以看到,這些都是利用Find方法的不同重載實現不同條件的處理的。

對於這個新接口,異步是一個重要的改變,那麼它的異步處理是如何的呢,我們看看上面兩個異步的實現操作,具體代碼如下所示。

        /// <summary>
        /// 查詢數據庫,檢查是否存在指定ID的對象(異步)
        /// </summary>
        /// <param name="key">對象的ID值</param>
        /// <returns>存在則返回指定的對象,否則返回Null</returns>
        public virtual async Task<T> FindByIDAsync(string id)
        {
            ArgumentValidation.CheckForEmptyString(id, "傳入的對象id為空");

            IMongoCollection<T> collection = GetCollection();
            return await collection.FindAsync(s=>s.Id == id).Result.FirstOrDefaultAsync(); 
        }

        /// <summary>
        /// 根據條件查詢數據庫,如果存在返回第一個對象(異步)
        /// </summary>
        /// <param name="query">條件表達式</param>
        /// <returns>存在則返回指定的第一個對象,否則返回默認值</returns>
        public virtual async Task<T> FindSingleAsync(FilterDefinition<T> query)
        {
            return await GetQueryable(query).SingleOrDefaultAsync();
        }

我們看到,上面的Collection或者GetQueryable(query)返回的對象,都提供給了以Async結尾的異步方法,因此對異步的封裝也是非常方便的,上面的GetQueryable(query)是另外一個公共的實現方法,具體代碼如下所示。

        /// <summary>
        /// 返回可查詢的記錄源
        /// </summary>
        /// <param name="query">查詢條件</param>
        /// <returns></returns>
        public virtual IFindFluent<T, T> GetQueryable(FilterDefinition<T> query)
        {
            return GetQueryable(query, this.SortPropertyName, this.IsDescending);
        }
        /// <summary>
        /// 根據條件表達式返回可查詢的記錄源
        /// </summary>
        /// <param name="query">查詢條件</param>
        /// <param name="sortPropertyName">排序表達式</param>
        /// <param name="isDescending">如果為true則為降序,否則為升序</param>
        /// <returns></returns>
        public virtual IFindFluent<T,T> GetQueryable(FilterDefinition<T> query, string sortPropertyName, bool isDescending = true)
        {
            IMongoCollection<T> collection = GetCollection();
            IFindFluent<T, T> queryable = collection.Find(query);

            var sort = this.IsDescending ? Builders<T>.Sort.Descending(this.SortPropertyName) : Builders<T>.Sort.Ascending(this.SortPropertyName);
            return queryable.Sort(sort);
        }

我們可以看到,它返回了IFindFluent<T, T>的對象,這個和以前返回的IMongoQuery對象又有不同,基本上,使用最新的接口,所有的實現都不太一樣,這也是因為MongoDB還在不停變化之中有關。

3、GetQueryable幾種方式

為了簡化代碼,方便使用,我們對獲取MongoDB的LINQ方式的處理做了簡單的封裝,提供了幾個GetQueryable的方式,具體代碼如下所示。

        /// <summary>
        /// 返回可查詢的記錄源
        /// </summary>
        /// <returns></returns>
        public virtual IQueryable<T> GetQueryable()
        {
            IMongoCollection<T> collection = GetCollection();
            IQueryable<T> query = collection.AsQueryable();

            return query.OrderBy(this.SortPropertyName, this.IsDescending);
        }
        /// <summary>
        /// 根據條件表達式返回可查詢的記錄源
        /// </summary>
        /// <param name="match">查詢條件</param>
        /// <param name="orderByProperty">排序表達式</param>
        /// <param name="isDescending">如果為true則為降序,否則為升序</param>
        /// <returns></returns>
        public virtual IQueryable<T> GetQueryable<TKey>(Expression<Func<T, bool>> match, Expression<Func<T, TKey>> orderByProperty, bool isDescending = true)
        {
            IMongoCollection<T> collection = GetCollection();
            IQueryable<T> query = collection.AsQueryable();

            if (match != null)
            {
                query = query.Where(match);
            }

            if (orderByProperty != null)
            {
                query = isDescending ? query.OrderByDescending(orderByProperty) : query.OrderBy(orderByProperty);
            }
            else
            {
                query = query.OrderBy(this.SortPropertyName, isDescending);
            }
            return query;
        }

以及基於FilterDefinition的條件處理,並返回IFindFluent<T,T>接口對象的代碼如下所示。

        /// <summary>
        /// 根據條件表達式返回可查詢的記錄源
        /// </summary>
        /// <param name="query">查詢條件</param>
        /// <param name="sortPropertyName">排序表達式</param>
        /// <param name="isDescending">如果為true則為降序,否則為升序</param>
        /// <returns></returns>
        public virtual IFindFluent<T,T> GetQueryable(FilterDefinition<T> query, string sortPropertyName, bool isDescending = true)
        {
            IMongoCollection<T> collection = GetCollection();
            IFindFluent<T, T> queryable = collection.Find(query);

            var sort = this.IsDescending ? Builders<T>.Sort.Descending(this.SortPropertyName) : Builders<T>.Sort.Ascending(this.SortPropertyName);
            return queryable.Sort(sort);
        }

4、集合的查詢操作封裝處理

基於上面的封裝,對結合的查詢,也是基於不同的條件進行處理,返回對應的列表的處理方式, 最簡單的是利用GetQueryable方式進行處理,代碼如下所示。

        /// <summary>
        /// 根據條件查詢數據庫,並返回對象集合
        /// </summary>
        /// <param name="match">條件表達式</param>
        /// <returns>指定對象的集合</returns>
        public virtual IList<T> Find(Expression<Func<T, bool>> match)
        {
            return GetQueryable(match).ToList();
        }

或者如下所示

        /// <summary>
        /// 根據條件查詢數據庫,並返回對象集合
        /// </summary>
        /// <param name="match">條件表達式</param>
        /// <returns>指定對象的集合</returns>
        public virtual IList<T> Find(FilterDefinition<T> query)
        {
            return GetQueryable(query).ToList();
        }

以及對排序字段,以及升降序的處理操作如下所示。

        /// <summary>
        /// 根據條件查詢數據庫,並返回對象集合
        /// </summary>
        /// <param name="match">條件表達式</param>
        /// <param name="orderByProperty">排序表達式</param>
        /// <param name="isDescending">如果為true則為降序,否則為升序</param>
        /// <returns></returns>
        public virtual IList<T> Find<TKey>(Expression<Func<T, bool>> match, Expression<Func<T, TKey>> orderByProperty, bool isDescending = true)
        {
            return GetQueryable<TKey>(match, orderByProperty, isDescending).ToList();
        }

        /// <summary>
        /// 根據條件查詢數據庫,並返回對象集合
        /// </summary>
        /// <param name="query">條件表達式</param>
        /// <param name="orderByProperty">排序字段</param>
        /// <param name="isDescending">如果為true則為降序,否則為升序</param>
        /// <returns></returns>
        public virtual IList<T> Find<TKey>(FilterDefinition<T> query, string orderByProperty, bool isDescending = true)
        {
            return GetQueryable(query, orderByProperty, isDescending).ToList();
        }

以及利用這些條件進行分頁的處理代碼如下所示。

        /// <summary>
        /// 根據條件查詢數據庫,並返回對象集合(用於分頁數據顯示)
        /// </summary>
        /// <param name="match">條件表達式</param>
        /// <param name="info">分頁實體</param>
        /// <returns>指定對象的集合</returns>
        public virtual IList<T> FindWithPager(Expression<Func<T, bool>> match, PagerInfo info)
        {
            int pageindex = (info.CurrenetPageIndex < 1) ? 1 : info.CurrenetPageIndex;
            int pageSize = (info.PageSize <= 0) ? 20 : info.PageSize;

            int excludedRows = (pageindex - 1) * pageSize;

            IQueryable<T> query = GetQueryable(match);
            info.RecordCount = query.Count();

            return query.Skip(excludedRows).Take(pageSize).ToList();
        }

        /// <summary>
        /// 根據條件查詢數據庫,並返回對象集合(用於分頁數據顯示)
        /// </summary>
        /// <param name="query">條件表達式</param>
        /// <param name="info">分頁實體</param>
        /// <returns>指定對象的集合</returns>
        public virtual IList<T> FindWithPager(FilterDefinition<T> query, PagerInfo info)
        {
            int pageindex = (info.CurrenetPageIndex < 1) ? 1 : info.CurrenetPageIndex;
            int pageSize = (info.PageSize <= 0) ? 20 : info.PageSize;

            int excludedRows = (pageindex - 1) * pageSize;

            var find = GetQueryable(query);
            info.RecordCount = (int)find.Count();

            return find.Skip(excludedRows).Limit(pageSize).ToList();
        }

對於異步的封裝處理,基本上也和上面的操作差不多,例如對於基礎的查詢,異步操作封裝如下所示。

        /// <summary>
        /// 根據條件查詢數據庫,並返回對象集合
        /// </summary>
        /// <param name="match">條件表達式</param>
        /// <returns>指定對象的集合</returns>
        public virtual async Task<IList<T>> FindAsync(Expression<Func<T, bool>> match)
        {
            return await Task.FromResult(GetQueryable(match).ToList());
        }

        /// <summary>
        /// 根據條件查詢數據庫,並返回對象集合
        /// </summary>
        /// <param name="query">條件表達式</param>
        /// <returns>指定對象的集合</returns>
        public virtual async Task<IList<T>> FindAsync(FilterDefinition<T> query)
        {
            return await GetQueryable(query).ToListAsync();
        }

復雜一點的分頁處理操作代碼封裝如下所示。

        /// <summary>
        /// 根據條件查詢數據庫,並返回對象集合(用於分頁數據顯示)
        /// </summary>
        /// <param name="match">條件表達式</param>
        /// <param name="info">分頁實體</param>
        /// <returns>指定對象的集合</returns>
        public virtual async Task<IList<T>> FindWithPagerAsync(Expression<Func<T, bool>> match, PagerInfo info)
        {
            int pageindex = (info.CurrenetPageIndex < 1) ? 1 : info.CurrenetPageIndex;
            int pageSize = (info.PageSize <= 0) ? 20 : info.PageSize;

            int excludedRows = (pageindex - 1) * pageSize;

            IQueryable<T> query = GetQueryable(match);
            info.RecordCount = query.Count();

            var result = query.Skip(excludedRows).Take(pageSize).ToList();
            return await Task.FromResult(result);
        }

        /// <summary>
        /// 根據條件查詢數據庫,並返回對象集合(用於分頁數據顯示)
        /// </summary>
        /// <param name="query">條件表達式</param>
        /// <param name="info">分頁實體</param>
        /// <returns>指定對象的集合</returns>
        public virtual async Task<IList<T>> FindWithPagerAsync(FilterDefinition<T> query, PagerInfo info)
        {
            int pageindex = (info.CurrenetPageIndex < 1) ? 1 : info.CurrenetPageIndex;
            int pageSize = (info.PageSize <= 0) ? 20 : info.PageSize;

            int excludedRows = (pageindex - 1) * pageSize;

            var queryable = GetQueryable(query);
            info.RecordCount = (int)queryable.Count();

            return await queryable.Skip(excludedRows).Limit(pageSize).ToListAsync();
        }

5、增刪改方法封裝處理

對於常規的增刪改操作,在新的MongoDB數據庫驅動裡面也修改了名稱,使用的時候也需要進行調整處理了。

        /// <summary>
        /// 插入指定對象到數據庫中
        /// </summary>
        /// <param name="t">指定的對象</param>
        public virtual void Insert(T t)
        {
            ArgumentValidation.CheckForNullReference(t, "傳入的對象t為空");

            IMongoCollection<T> collection = GetCollection();
            collection.InsertOne(t);
        }

異步的操作實現如下所示。

        /// <summary>
        /// 插入指定對象到數據庫中
        /// </summary>
        /// <param name="t">指定的對象</param>
        public virtual async Task InsertAsync(T t)
        {
            ArgumentValidation.CheckForNullReference(t, "傳入的對象t為空");

            IMongoCollection<T> collection = GetCollection();
            await collection.InsertOneAsync(t);
        }

批量插入記錄的操作如下所示。

        /// <summary>
        /// 插入指定對象集合到數據庫中
        /// </summary>
        /// <param name="list">指定的對象集合</param>
        public virtual void InsertBatch(IEnumerable<T> list)
        {
            ArgumentValidation.CheckForNullReference(list, "傳入的對象list為空");

            IMongoCollection<T> collection = GetCollection();
            collection.InsertMany(list);
        }

對應的異步操作處理如下所示,這些都是利用原生支持的異步處理接口實現的。

        /// <summary>
        /// 插入指定對象集合到數據庫中
        /// </summary>
        /// <param name="list">指定的對象集合</param>
        public virtual async Task InsertBatchAsync(IEnumerable<T> list)
        {
            ArgumentValidation.CheckForNullReference(list, "傳入的對象list為空");

            IMongoCollection<T> collection = GetCollection();
            await collection.InsertManyAsync(list);
        }

更新操作,有一種整個替換更新,還有一個是部分更新,它們兩者是有區別的,如對於替換更新的操作,它的接口封裝處理如下所示

        /// <summary>
        /// 更新對象屬性到數據庫中
        /// </summary>
        /// <param name="t">指定的對象</param>
        /// <param name="id">主鍵的值</param>
        /// <returns>執行成功返回<c>true</c>,否則為<c>false</c></returns>
        public virtual bool Update(T t, string id)
        {
            ArgumentValidation.CheckForNullReference(t, "傳入的對象t為空");
            ArgumentValidation.CheckForEmptyString(id, "傳入的對象id為空");

            bool result = false;
            IMongoCollection<T> collection = GetCollection();
            //使用 IsUpsert = true ,如果沒有記錄則寫入
            var update = collection.ReplaceOne(s => s.Id == id, t, new UpdateOptions() { IsUpsert = true });
            result = update != null && update.ModifiedCount > 0;

            return result;
        }

如果對於部分字段的更新,那麼操作如下所示 ,主要是利用UpdateDefinition對象來指定需要更新那些字段屬性及值等信息。

        /// <summary>
        /// 封裝處理更新的操作(部分字段更新)
        /// </summary>
        /// <param name="id">主鍵的值</param>
        /// <param name="update">更新對象</param>
        /// <returns>執行成功返回<c>true</c>,否則為<c>false</c></returns>
        public virtual bool Update(string id, UpdateDefinition<T> update)
        {
            ArgumentValidation.CheckForNullReference(update, "傳入的對象update為空");
            ArgumentValidation.CheckForEmptyString(id, "傳入的對象id為空");

            IMongoCollection<T> collection = GetCollection();
            var result = collection.UpdateOne(s => s.Id == id, update, new UpdateOptions() { IsUpsert = true });
            return result != null && result.ModifiedCount > 0;
        }

上面的異步更新操作如下所示。

        /// <summary>
        /// 封裝處理更新的操作(部分字段更新)
        /// </summary>
        /// <param name="id">主鍵的值</param>
        /// <param name="update">更新對象</param>
        /// <returns>執行成功返回<c>true</c>,否則為<c>false</c></returns>
        public virtual async Task<bool> UpdateAsync(string id, UpdateDefinition<T> update)
        {
            ArgumentValidation.CheckForNullReference(update, "傳入的對象update為空");
            ArgumentValidation.CheckForEmptyString(id, "傳入的對象id為空");

            IMongoCollection<T> collection = GetCollection();
            var result = await collection.UpdateOneAsync(s => s.Id == id, update, new UpdateOptions() { IsUpsert = true });

            var sucess = result != null && result.ModifiedCount > 0;
            return await Task.FromResult(sucess);
        }

刪除的操作也是類似的了,基本上和上面的處理方式接近,順便列出來供參考學習。

        /// <summary>
        /// 根據指定對象的ID,從數據庫中刪除指定對象
        /// </summary>
        /// <param name="id">對象的ID</param>
        /// <returns>執行成功返回<c>true</c>,否則為<c>false</c>。</returns>
        public virtual bool Delete(string id)
        {
            ArgumentValidation.CheckForEmptyString(id, "傳入的對象id為空");

            IMongoCollection<T> collection = GetCollection();
            var result = collection.DeleteOne(s=> s.Id == id);
            return result != null && result.DeletedCount > 0;
        }

        /// <summary>
        /// 根據指定對象的ID,從數據庫中刪除指定指定的對象
        /// </summary>
        /// <param name="idList">對象的ID集合</param>
        /// <returns>執行成功返回<c>true</c>,否則為<c>false</c>。</returns>
        public virtual bool DeleteBatch(List<string> idList)
        {
            ArgumentValidation.CheckForNullReference(idList, "傳入的對象idList為空");

            IMongoCollection<T> collection = GetCollection();
            var query = Query.In("_id", new BsonArray(idList));
            var result = collection.DeleteMany(s => idList.Contains(s.Id));
            return result != null && result.DeletedCount > 0;
        }

如果根據條件的刪除,也可以利用條件定義的兩種方式,具體代碼如下所示。

        /// <summary>
        /// 根據指定條件,從數據庫中刪除指定對象
        /// </summary>
        /// <param name="match">條件表達式</param>
        /// <returns>執行成功返回<c>true</c>,否則為<c>false</c>。</returns>
        public virtual bool DeleteByExpression(Expression<Func<T, bool>> match)
        {
            IMongoCollection<T> collection = GetCollection();
            collection.AsQueryable().Where(match).ToList().ForEach(s => collection.DeleteOne(t => t.Id == s.Id));
            return true;
        }

        /// <summary>
        /// 根據指定條件,從數據庫中刪除指定對象
        /// </summary>
        /// <param name="match">條件表達式</param>
        /// <returns>執行成功返回<c>true</c>,否則為<c>false</c>。</returns>
        public virtual bool DeleteByQuery(FilterDefinition<T> query)
        {
            IMongoCollection<T> collection = GetCollection();
            var result = collection.DeleteMany(query);
            return result != null && result.DeletedCount > 0;
        } 

6、數據訪問子類的封裝和方法調用

好了,基本上上面大多數使用的方法都發布出來了,封裝的原則就是希望數據訪問層子類能夠簡化代碼,減少不必要的復制粘貼,而且必要的時候, 也可以對具體的接口進行重寫,實現更強大的處理控制。

例如對於上面的基類,我們在具體的集合對象封裝的時候,需要繼承於BaseDAL<T>這樣的方式,這樣可以利用基類豐富的接口,簡化子類的代碼,如User集合類的代碼如下所示。

   /// <summary>
    /// User集合(表)的數據訪問類
    /// </summary>
    public class User : BaseDAL<UserInfo>
    {
        /// <summary>
        /// 默認構造函數
        /// </summary>
        public User() 
        {
            this.entitysName = "users";//對象在數據庫的集合名稱
        }

        /// <summary>
        /// 為用戶增加歲數
        /// </summary>
        /// <param name="id">記錄ID</param>
        /// <param name="addAge">待增加的歲數</param>
        /// <returns></returns>
        public bool IncreaseAge(string id, int addAge)
        {
            var collection = GetCollection();
            var update = Builders<UserInfo>.Update.Inc(s => s.Age, addAge);
            var result = collection.UpdateOne(s => s.Id == id, update);
            return result != null && result.ModifiedCount > 0;
        }

        /// <summary>
        /// 單獨修改用戶的名稱
        /// </summary>
        /// <param name="id">記錄ID</param>
        /// <param name="newName">用戶新名稱</param>
        /// <returns></returns>
        public bool UpdateName(string id, string newName)
        {
            var collection = GetCollection();
            var update = Builders<UserInfo>.Update.Set(s => s.Name, newName);
            var result = collection.UpdateOne(s => s.Id == id, update);
            return result != null && result.ModifiedCount > 0;
        }
    }

在界面層使用的時候,只需要聲明一個對應的User數據訪問類dal對象,就可以利用它的相關接口進行對應的數據操作了,如下代碼所示。

            IList<UserInfo> members = dal.Find(s => s.Name.StartsWith("Test"));
            foreach (UserInfo info in members)
            {
                Console.WriteLine(info.Id + ", " + info.Name);
            }
            var user = dal.FindSingle(s => s.Id == "56815e6634ab091e1406ec68");
            if(user != null)
            {
                Console.WriteLine(user.Name);
            }

對於部分字段的更新處理,在界面上,我們可以利用封裝好的接口進行處理,如下所示。

        /// <summary>
        /// 測試部分字段修改的處理
        /// </summary>
        private void btnAddAge_Click(object sender, EventArgs e)
        {
            UserInfo info = dal.GetAll()[0];
            if(info != null)
            {
                Console.WriteLine("Age before Incr:" + info.Age);

                int addAge = 10;
                dal.IncreaseAge(info.Id, addAge);

                info = dal.FindByID(info.Id);
                Console.WriteLine("Age after Incr:" + info.Age);


                Console.WriteLine("Name before modify:" + info.Name);
                var update = Builders<UserInfo>.Update.Set(s => s.Name, info.Name + DateTime.Now.Second);
                dal.Update(info.Id, update);

                info = dal.FindByID(info.Id);
                Console.WriteLine("Name after modify:" + info.Name);
            }
        }

對於異步接口的調用代碼,如下所示。

        /// <summary>
        /// 異步操作的調用
        /// </summary>
        private async void btnAsync_Click(object sender, EventArgs e)
        {
            UserInfo newInfo = new UserInfo();
            newInfo.Name = "Ping" + DateTime.Now.ToString();
            newInfo.Age = DateTime.Now.Minute;
            newInfo.Hobby = "乒乓球";
            await dal.InsertAsync(newInfo);

            var list = await dal.FindAsync(s => s.Age < 30);
            foreach (UserInfo info in list)
            {
                Console.WriteLine(info.Id + ", " + info.Name);
            }
            Console.WriteLine(newInfo.Id);
        }

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved