65.9K
CodeProject 正在变化。 阅读更多。
Home

支持 LINQ 的 MongoDB 通用 DAO

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.86/5 (8投票s)

2012年11月8日

CPOL

1分钟阅读

viewsIcon

33478

一个支持LINQ的MongoDB泛型DAO模式的C#实现。

引言

本文介绍如何使用MongoDB C#驱动程序实现泛型DAO模式,以及如何在简单的ASP.NET MVC 3应用程序中使用它。

MongoDBEntity 

为了表示MongoDB中的所有文档,我们可以使用任何继承自抽象MongoDB实体的类。 

using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Bson;

namespace MongoDbGenericDao
{
    public abstract class MongoDBEntity
    {
        [BsonRepresentation(BsonType.ObjectId)]
        public string Id { get; set; }
    }
}

MongoDBEntity被标记为abstract,因此只能通过特定的MongoDBEntity DAO实现来使用。

[BsonRepresentation(BsonType.ObjectId)]定义了哪个属性将被用作MongoDB文档序列化中的"_id"标识符。

Author类将由GenericDao使用。

namespace Modal
{
    public class Author : MongoDBEntity
    {
        public string Name { get; set; }
        public string Email { get; set; }
    }
}

泛型DAO接口

using System;
using System.Collections.Generic;

namespace MongoDbGenericDao.Interfaces
{
    public interface IDao<T, ID> where T : MongoDBEntity
    {
        T Save(T pobject);
        T GetByID(ID id);
        T GetByCondition(System.Linq.Expressions.Expression<Func<T, bool>> condition);
        IEnumerable<T> GetAll();
        IEnumerable<T> GetAll(System.Linq.Expressions.Expression<Func<T, bool>> condition);
        IEnumerable<T> GetAll(System.Linq.Expressions.Expression<Func<T, bool>> condition, int maxresult, bool orderByDescending);
        IEnumerable<T> Paginate(System.Linq.Expressions.Expression<Func<T, bool>> func, int pagesize, int page, bool pOrderByDescending);
        void Delete(T pobject);
        long Count(System.Linq.Expressions.Expression<Func<T, bool>> condition);
    }
}

IDao<T, ID>

  1. T代表一个MongoDBEntity
  2. ID代表MongoDB的"_id"标识符类型,默认为string

泛型DAO实现

using System;
using System.Collections.Generic;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using MongoDB.Driver.Builders;
using MongoDB.Bson;
using System.Linq;

namespace MongoDbGenericDao
{
    public class MongoDBGenericDao<T> : Interfaces.IDao<T, string> where T : MongoDBEntity
    {
        private MongoDatabase _repository;
        private readonly string collectioname = typeof(T).Name;

        public MongoDBGenericDao(string pConnectionstring)
        {
            var conn = new MongoConnectionStringBuilder(pConnectionstring);
            _repository = MongoServer.Create(conn).GetDatabase(conn.DatabaseName);
        }

        public T GetByID(string _id)
        {
            return _repository.GetCollection<T>(collectioname).FindOne(Query.EQ("_id", new ObjectId(_id)));
        }

        public IEnumerable<T> GetAll()
        {
            return _repository.GetCollection<T>(collectioname).FindAll();
        }

        public T GetByCondition(System.Linq.Expressions.Expression<Func<T, bool>> condition)
        {
            return _repository.GetCollection<T>(collectioname).AsQueryable().Where(condition).FirstOrDefault();
        }

        public IEnumerable<T> GetAll(System.Linq.Expressions.Expression<Func<T, bool>> condition)
        {
            return _repository.GetCollection<T>(collectioname).AsQueryable().Where(condition).ToList();
        }

        public IEnumerable<T> GetAll(System.Linq.Expressions.Expression<Func<T, bool>> condition, 
               int maxresult, bool orderByDescending = false)
        {
            var query = _repository.GetCollection<T>(collectioname).AsQueryable().Where(condition);

            if (orderByDescending)
                query.OrderByDescending(x => x.Id);
            else
                query.OrderBy(x => x.Id);

            return query.Take(maxresult);
        }

        public T Save(T pobject)
        {
            _repository.GetCollection<T>(collectioname).Save(pobject);
            return pobject;
        }

        public void Delete(T pobject)
        {
            _repository.GetCollection<T>(collectioname).Remove(Query.EQ("_id", new ObjectId(pobject.Id)));
        }

        public long Count(System.Linq.Expressions.Expression<Func<T, bool>> condition)
        {
            return _repository.GetCollection<T>(collectioname).AsQueryable().LongCount();
        }

        public IEnumerable<T> Paginate(System.Linq.Expressions.Expression<Func<T, bool>> func, 
               int pagesize, int page, bool pOrderByDescending = false)
        {
            var query = _repository.GetCollection<T>(collectioname).AsQueryable().Where(func);

            if (pOrderByDescending)
                query.OrderByDescending(x => x.Id);
            else
                query.OrderBy(x => x.Id);

            return query.Skip(pagesize * (page - 1)).Take(pagesize);
        }
    }
}

此实现提供所有CRUD方法以及LINQ支持和一个有用的Paginate方法。

LINQ支持是C#驱动程序的原生特性。

业务实现

要使用此代码,只需继承GenericDao<t,>类并指定IDao<t,>接口。 

using MeuCondominio.Business.Interfaces;
using MeuCondominio.Modal.Concrete;
using MongoDbGenericDao;

namespace MeuCondominio.Business.Business
{
    public class BAuthor : MongoDBGenericDao<Author>, IDao<Author,string>
    {
        public BAuthor(string connectionstring)
            : base(connectionstring)
        {

        }
    }
}

用法

创建一个新的ASP.NET MVC 3应用程序,并在web.config文件中添加MongoDB连接字符串。

<connectionstrings>
    <clear />
    <add name="MongoServerSettings" connectionstring="server=localhost;database=test"> </add>
</connectionstrings>

在控制器中,只需创建一个来自GenericDAO的业务变量即可。 

// GET: /Home/
public ActionResult Index()
{
    var _BAuthor = new MongoDbGenericDao.MongoDBGenericDao<Author>(
        WebConfigurationManager.ConnectionStrings["MongoServerSettings"].ConnectionString);

    //get 10 authors
    return View(_BAuthor.GetAll().Take(10).ToList());
}	

[HttpDelete]
public ActionResult Remove(string Id)
{
    var _BAuthor = new MongoDbGenericDao.MongoDBGenericDao<Author>(
      WebConfigurationManager.ConnectionStrings["MongoServerSettings"].ConnectionString);

    //get author by Id
    var author = _BAuthor.GetByID(Id);

    //remove an author
    _BAuthor.Delete(author);

    return RedirectToAction("Index");
}

[HttpPost]
public ActionResult AddAuthor(string name, string email)
{
    Author author = new Author
    {
        Name = name,
        Email = email
    };

    var _BAuthor = new MongoDbGenericDao.MongoDBGenericDao<Postagem>(
      WebConfigurationManager.ConnectionStrings["MongoServerSettings"].ConnectionString);

    //Adds the author object and redirects to "Index" action
    _BAuthor.Save(author);

    return RedirectToAction("Index");
}

关注点

一个好的实践是使用依赖注入框架(如NinjectStructureMap)来注入业务类。

您可以使用我在github上的MongoDbGenericDAO项目,我很乐意改进这个项目。 

© . All rights reserved.