如何实现针对mongodb的通用存储库
本文关键字:mongodb 存储 何实现 实现 | 更新日期: 2023-09-27 18:18:57
我是mongodb的新手,我正在为一个新项目开发mvc4 web应用程序。
我想使用存储库模式,将与mongodb上下文进行数据库级通信。
简单的接口,我已经使用实体框架4.0如下。查找成员对我来说是有问题的地方。我不知道如何继续与他们与mongodb上下文。
public interface IRepository<T> where T : class
{
void Add(T entity);
void Remove(T entity);
IQueryable<T> Find(Expression<Func<T, bool>> predicate);
//IQueryable<T> FindAll();
}
我有一个非常简单的模型,叫做Hero,它来自ImongoEntity,它提供了一个名为accessId的成员。
public class Hero : MongoDB.Kennedy.IMongoEntity
{
public ObjectId _id { get; set; }
public string Name { get; set; }
public string Alias { get; set; }
public string _accessId { get; set;}
}
Context类是非常简单的,你可以看到英雄的集合被暴露为IQueryable属性。
public class MongoDataConetext: MongoDB.Kennedy.ConcurrentDataContext
{
public MongoDataConetext(string databaseName, string serverName="localhost") : base(databaseName, serverName)
{
}
public IQueryable<Hero> Heros {
get {
return base.GetCollection<Hero>().AsQueryable();
}
}
}
现在在我的存储库中最简单的方法是添加和删除它们成功地与mongodb上下文交谈,并从mongodb中添加或删除实体。然而,找到方法给了我编译器级别的错误。我需要帮助我的查找和查找所有方法。我之所以使用通用型,是因为我需要我的存储库类来存储英雄、解决方案、项目、用户和类别等实体。
public class Repository<T> : IRepository<T> where T : class, IMongoEntity
{
private readonly MongoDataConetext _ctx;
public Repository(MongoDataConetext ctx)
{
_ctx = ctx;
}
public void Add(T entity)
{
_ctx.Save(entity);
}
public void Remove(T entity)
{
_ctx.Delete(entity);
}
public IQueryable<T> Find(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
{
_ctx.Heros.Where(predicate);
//throw new NotImplementedException();
}
//public IQueryable<T> FindAll()
//{
// throw new NotImplementedException();
//}
}
如果您对类似于Rob Connery和NBlog存储代码的实现感兴趣,但使用mongodb csharp驱动程序2.0(即异步),您可以查看:
https://github.com/alexandre-spieser/mongodb-generic-repository你可以从BaseMongoRepository继承一个自定义存储库。
public interface ITestRepository : IBaseMongoRepository
{
void DropTestCollection<TDocument>();
void DropTestCollection<TDocument>(string partitionKey);
}
public class TestRepository : BaseMongoRepository, ITestRepository
{
public TestRepository(string connectionString, string databaseName) : base(connectionString, databaseName)
{
}
public void DropTestCollection<TDocument>()
{
MongoDbContext.DropCollection<TDocument>();
}
public void DropTestCollection<TDocument>(string partitionKey)
{
MongoDbContext.DropCollection<TDocument>(partitionKey);
}
}
更新:它现在可以作为自己的nuget包使用:
Install-Package MongoDbGenericRepository
看起来您正在尝试对您的集合使用LINQ。这是完美的。如果你只是公开一个IQueryable属性,而不是编写一个Find()
方法,你可以更容易地做到这一点。
这是你上面的一个例子:
public class HeroRepository : IRepository<Heros> where T : class, IMongoEntity
{
// ...
public IQueryable<Heros> Heros
{
get
{
return _ctx.GetCollection<Heros>().AsQueryable();
// Careful there, doing this from memory, may be a little off...
}
}
}
当然,当你使用这个类时,只需:
var r = new HeroRepository();
var heros = r.Heros.Where(r => r.SuperPowerLevel > 20);
通用
public class MongoDatabase<T> : IDatabase<T> where T : class, new()
{
private static string connectionString = "connectionString";
private static IMongoClient server = new MongoClient(connectionString);
private string collectionName;
private IMongoDatabase db;
protected IMongoCollection<T> Collection
{
get
{
return db.GetCollection<T>(collectionName);
}
set
{
Collection = value;
}
}
public MongoDatabase(string collection)
{
collectionName = collection;
db = server.GetDatabase(MongoUrl.Create(connectionString).DatabaseName);
}
public IMongoQueryable<T> Query
{
get
{
return Collection.AsQueryable<T>();
}
set
{
Query = value;
}
}
public T GetOne(Expression<Func<T, bool>> expression)
{
return Collection.Find(expression).SingleOrDefault();
}
public T FindOneAndUpdate(Expression<Func<T, bool>> expression, UpdateDefinition<T> update, FindOneAndUpdateOptions<T> option)
{
return Collection.FindOneAndUpdate(expression, update, option);
}
public void UpdateOne(Expression<Func<T, bool>> expression, UpdateDefinition<T> update)
{
Collection.UpdateOne(expression, update);
}
public void DeleteOne(Expression<Func<T, bool>> expression)
{
Collection.DeleteOne(expression);
}
public void InsertMany(IEnumerable<T> items)
{
Collection.InsertMany(items);
}
public void InsertOne(T item)
{
Collection.InsertOne(item);
}
}
İnterface
public interface IDatabase<T> where T : class, new()
{
IMongoQueryable<T> Query { get; set; }
T GetOne(Expression<Func<T, bool>> expression);
T FindOneAndUpdate(Expression<Func<T, bool>> expression, UpdateDefinition<T> update, FindOneAndUpdateOptions<T> option);
void UpdateOne(Expression<Func<T, bool>> expression, UpdateDefinition<T> update);
void DeleteOne(Expression<Func<T, bool>> expression);
void InsertMany(IEnumerable<T> items);
void InsertOne(T item);
}
我知道这是一篇相当旧的文章,但我想与您分享在Github上实现的MongoRepository项目或作为NuGet包下载
注意:我试图实现MongoDB存储库的问题之一是不同的行为取决于MongoDB驱动程序版本或或多或少相同,. net框架。MongoRepository项目(在上面的链接中)已经用。net 3.5, 4.0和4.5框架的不同代码版本解决了这个问题,这些框架使用不同版本的MongoDB驱动程序(检查MongoDB驱动程序兼容性),这非常有帮助。