7

我是 mongodb 的新手,我正在为一个新项目开发 mvc4 Web 应用程序。

我想使用将与 mongodb 上下文进行数据库级通信的存储库模式。

下面是我与 Entity Framework 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 属性公开的 Heros 集合。

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 中添加或删除实体。但是 Find 方法给了我编译器级别的错误。我需要帮助来查找和查找所有方法。我正在使用泛型,因为我需要我的存储库类来存储英雄、解决方案、项目、用户和类别等实体。

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();
    //}
}
4

4 回答 4

5

如果您对类似于 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
于 2016-02-27T12:25:20.013 回答
4

看起来您正在尝试对您的集合使用 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);
于 2013-06-19T14:43:33.197 回答
4

通用的

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);
        }
    }

界面

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);
}
于 2018-05-03T19:40:01.973 回答
0

我知道这是一个相当老的帖子,但我想与您分享在Github实现的 MongoRepository 项目或下载为NuGet 包

注意:我尝试实现 MongoDB 存储库的一个问题是,根据 MongoDB 驱动程序版本或 .NET 框架或多或少相同,行为会有所不同。MongoRepository 项目(在上面的链接中)通过使用不同版本的 MongoDB 驱动程序(检查MongoDB 驱动程序兼容性)的 .net 3.5、4.0 和 4.5 框架的不同代码版本解决了这个问题,这非常有帮助。

于 2015-06-30T10:48:58.780 回答