支持 LINQ 的 MongoDB 通用 DAO






4.86/5 (8投票s)
一个支持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>
中
T
代表一个MongoDBEntity
类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");
}
关注点
一个好的实践是使用依赖注入框架(如Ninject或StructureMap)来注入业务类。
您可以使用我在github上的MongoDbGenericDAO项目,我很乐意改进这个项目。