The provider for the source IQueryable doesn't implement IAsyncQueryProvider - c#

I have some codes like below, I want to write unit tests my method. But I'm stuck in async methods. Can you help me please ?
public class Panel
{
public int Id { get; set; }
[Required] public double Latitude { get; set; }
public double Longitude { get; set; }
[Required] public string Serial { get; set; }
public string Brand { get; set; }
}
public class CrossSolarDbContext : DbContext
{
public CrossSolarDbContext()
{
}
public CrossSolarDbContext(DbContextOptions<CrossSolarDbContext> options) : base(options)
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
}
}
public interface IGenericRepository<T>
{
Task<T> GetAsync(string id);
IQueryable<T> Query();
Task InsertAsync(T entity);
Task UpdateAsync(T entity);
}
public abstract class GenericRepository<T> : IGenericRepository<T>
where T : class, new()
{
protected CrossSolarDbContext _dbContext { get; set; }
public async Task<T> GetAsync(string id)
{
return await _dbContext.FindAsync<T>(id);
}
public IQueryable<T> Query()
{
return _dbContext.Set<T>().AsQueryable();
}
public async Task InsertAsync(T entity)
{
_dbContext.Set<T>().Add(entity);
await _dbContext.SaveChangesAsync();
}
public async Task UpdateAsync(T entity)
{
_dbContext.Entry(entity).State = EntityState.Modified;
await _dbContext.SaveChangesAsync();
}
}
public interface IPanelRepository : IGenericRepository<Panel> { }
public class PanelRepository : GenericRepository<Panel>, IPanelRepository
{
public PanelRepository(CrossSolarDbContext dbContext)
{
_dbContext = dbContext;
}
}
[Route("[controller]")]
public class PanelController : Controller
{
private readonly IPanelRepository _panelRepository;
public PanelController(IPanelRepository panelRepository)
{
_panelRepository = panelRepository;
}
// GET panel/XXXX1111YYYY2222
[HttpGet("{panelId}")]
public async Task<IActionResult> Get([FromRoute] string panelId)
{
Panel panel = await _panelRepository.Query().FirstOrDefaultAsync(x => x.Serial.Equals(panelId, StringComparison.CurrentCultureIgnoreCase));
if (panel == null) return NotFound();
return Ok(panel);
}
}
public class PanelControllerTests
{
private readonly PanelController _panelController;
private static readonly Panel panel = new Panel { Id = 1, Brand = "Areva", Latitude = 12.345678, Longitude = 98.7655432, Serial = "AAAA1111BBBB2222" };
private readonly IQueryable<Panel> panels = new List<Panel>() { panel }.AsQueryable();
private readonly Mock<IPanelRepository> _panelRepositoryMock = new Mock<IPanelRepository>();
public PanelControllerTests()
{
_panelRepositoryMock.Setup(x => x.Query()).Returns(panels);
// I also tried this. I got another error 'Invalid setup on an extension method: x => x.FirstOrDefaultAsync<Panel>(It.IsAny<Expression<Func<Panel, Boolean>>>(), CancellationToken)'
// _panelRepositoryMock.As<IQueryable<Panel>>().Setup(x => x.FirstOrDefaultAsync(It.IsAny<Expression<Func<Panel, bool>>>(), default(CancellationToken))).ReturnsAsync(panel);
_panelController = new PanelController(_panelRepositoryMock.Object);
}
[Fact]
public async Task Register_ShouldInsertOneHourElectricity()
{
IActionResult result = await _panelController.Get("AAAA1111BBBB2222");
Assert.NotNull(result);
var createdResult = result as CreatedResult;
Assert.NotNull(createdResult);
Assert.Equal(201, createdResult.StatusCode);
}
}
I'm getting this error
The provider for the source IQueryable doesn't implement IAsyncQueryProvider. Only providers that implement IEntityQueryProvider can be used for Entity Framework asynchronous operations.
I think that I need to mock 'FirstOrDefaultAsync' but I'm not sure and I don't know how to do. I tried something, however it couldn't be compiled.

I get stuck on this issue today and this lib resolve it for me https://github.com/romantitov/MockQueryable completely, please refer:
Mocking Entity Framework Core operations such ToListAsync, FirstOrDefaultAsync etc.
//1 - create a List<T> with test items
var users = new List<UserEntity>()
{
new UserEntity{LastName = "ExistLastName", DateOfBirth = DateTime.Parse("01/20/2012")},
...
};
//2 - build mock by extension
var mock = users.AsQueryable().BuildMock();
//3 - setup the mock as Queryable for Moq
_userRepository.Setup(x => x.GetQueryable()).Returns(mock.Object);
//3 - setup the mock as Queryable for NSubstitute
_userRepository.GetQueryable().Returns(mock);

You could implement an AsyncEnumerable which can be used like this:
private readonly IQueryable<Panel> panels = new AsyncEnumerable(new List<Panel>()
{
panel
});
Here is the implementation of it:
public class AsyncEnumerable<T> : EnumerableQuery<T>, IAsyncEnumerable<T>, IQueryable<T>
{
public AsyncEnumerable(IEnumerable<T> enumerable) : base(enumerable) { }
public AsyncEnumerable(Expression expression) : base(expression) { }
public IAsyncEnumerator<T> GetEnumerator()
{
return new AsyncEnumerator<T>(this.AsEnumerable().GetEnumerator());
}
IQueryProvider IQueryable.Provider => new AsyncQueryProvider<T>(this);
}
The AsyncEnumerator class:
public class AsyncEnumerator<T> : IAsyncEnumerator<T>
{
private readonly IEnumerator<T> _inner;
public AsyncEnumerator(IEnumerator<T> inner)
{
_inner = inner;
}
public void Dispose()
{
_inner.Dispose();
}
public T Current => _inner.Current;
public Task<bool> MoveNext(CancellationToken cancellationToken)
{
return Task.FromResult(_inner.MoveNext());
}
}
The AsyncQueryProvider class:
public class AsyncQueryProvider<TEntity> : IAsyncQueryProvider
{
private readonly IQueryProvider _inner;
internal AsyncQueryProvider(IQueryProvider inner)
{
_inner = inner;
}
public IQueryable CreateQuery(Expression expression)
{
return new AsyncEnumerable<TEntity>(expression);
}
public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
{
return new AsyncEnumerable<TElement>(expression);
}
public object Execute(Expression expression)
{
return _inner.Execute(expression);
}
public TResult Execute<TResult>(Expression expression)
{
return _inner.Execute<TResult>(expression);
}
public IAsyncEnumerable<TResult> ExecuteAsync<TResult>(Expression expression)
{
return new AsyncEnumerable<TResult>(expression);
}
public Task<TResult> ExecuteAsync<TResult>(Expression expression, CancellationToken cancellationToken)
{
return Task.FromResult(Execute<TResult>(expression));
}
}

This is because of your mocking approach; your mock provider just returns panels for Query, and panels is a simple object with LINQ-to-Objects exposing it as queryable:
private readonly IQueryable<Panel> panels = new List<Panel>() { panel }.AsQueryable();
Indeed, this does not implement IAsyncQueryProvider. If you can get hold of the regular query provider, you should be able to wrap that with a fake always-synchronous version to spoof it (just use return Task.FromResult(Execute(expression))), but frankly I'm not sure that this would be a useful test... at that point you're skipping so many of the important realities of async that it probably isn't worth it.

For issue in entity framework core ,use Moq.EntityFrameworkCore library and setup your dbset as below:
contextMock.Setup(x => x.entity).ReturnsDbSet(entityList);

I was facing the same issue and solved it that way:
Instead of having my method public async Task I switched it to public void and then resolved the asynchronous methods with .GetAwaiter() instead of await.

When querying for panel, removing the async in firstordefault.
Also remove the async from tolist when querying for analytics

Related

Mocking IEnumerable<T> for each class that implements <T> using Moq

I have the following interface
public interface ICommand<TResult, TModel>
{
Task<TResult> DoWorkAsync(TModel model);
}
Which is implemented by one or more such Command classes:
public class MyCommand1 : ICommand<Response, Model>()
{
public async Task<Response> DoWorkAsync(Model model) {
// do something
}
}
public class MyCommand2 : ICommand<Response, Model>()
{
public async Task<Response> DoWorkAsync(Model model) {
// do something else
}
}
The Respose and Model classes are as follows:
public class Response
{
public bool IsSuccessful {get;set;}
}
public class Model
{
public Guid Id {get;set;}
public string Name {get;set;}
}
Then I have an orchestrator class that has a dependency on an IEnumerable of IEnumerable<ICommand<Response, Model>>
public class MyOrchestrator
{
private readonly IEnumerable<ICommand<Response, Model>> _commands;
public MyOrchestrator(IEnumerable<ICommand<Response, Model>> commands)
{
_commands = commands;
}
public async Task ExecuteAsync(Model model)
{
myCommand1_Response = await _commands
.OfType<MyCommand1>()
.First()
.DoWorkAsync(model);
myCommand2_Response = await _commands
.OfType<MyCommand2>()
.First()
.DoWorkAsync(model);
// other operations
}
}
Now in my test I'm trying to mock the MyOrchestrator class's dependency IEnumerable<ICommand<Response, Model>> for each of the MyCommand types. How can I achieve this?
The problem is that MyCommand2 and MyCommand1 are concrete classes. You'll either need to make them be IMyCommand1 and IMyCommand2 or make DoWorkAsync virtual.
I think you could simplify your orchestator which would make mocking trivial.
public class MyOrchestrator
{
...
public MyOrchestrator(ICommand<Response, Model> command1, ICommand<Response, Model> command2)
{
this.command1 = command1 ?? throw...;
this.command2 = command2 ?? throw...;
}
public async Task ExecuteAsync(Model model)
{
myCommand1_Response = await command1.DoWorkAsync(model);
myCommand2_Response = await command1.DoWorkAsync(model);
// other operations
}
}
Now mocking this is nothing special.
var mockCommand1 = new Mock<ICommand<Response, Model>>(MockBehaviour.Strict);
...
var tested = new MyOrchestrator(command1: mockCommand1.Object, ...);

Generic CQRS Query handler with custom return type

I am trying to build a generic query handler using the MediatR (v8) library. Lets jump to the code:
First of all I have an abstract query class like this:
public abstract class Query<TQueryResult> : IRequest<TQueryResult>
{
public Guid Id { get; } = Guid.NewGuid();
public DateTime Timestamp { get; }
protected Query()
{
Timestamp = DateTime.Now;
}
}
From the corresponding query handler I would like to return a Result wrapper object, which looks as the following:
public class Result<T>
{
public T Payload { get; }
public string FailureReason { get; }
public bool IsSuccess => FailureReason == null;
public Result(T payload)
{
Payload = payload;
}
public Result(string failureReason)
{
FailureReason = failureReason;
}
public static Result<T> Success(T payload)
=> new Result<T>(payload);
public static Result<T> Failure(string reason)
=> new Result<T>(reason);
public static implicit operator bool(Result<T> result) => result.IsSuccess;
}
And last but not least, lets see the query handler:
public abstract class AbstractQueryHandler<TQuery, TQueryResult, TResultValue> : IRequestHandler<TQuery, TQueryResult>
where TQuery : Query<TQueryResult>
where TQueryResult : class
{
public Task<TQueryResult> Handle(TQuery request, CancellationToken cancellationToken)
{
try
{
return HandleQuery(request);
}
catch (Exception e)
{
return Task.FromResult(Result<TResultValue>.Failure(GetFailureMessage(e)) as TQueryResult);
}
}
public abstract Task<TQueryResult> HandleQuery(TQuery request);
private static string GetFailureMessage(Exception e)
{
return "There was an error while executing query: \r\n" + e.Message;
}
}
To be honest I am not pleased with this solution due to the three type parameters I have in the query handler. Let's see some corresponding tests to reveal my concerns regarding. First the test-helper objects:
public class ExampleDto
{
public string Name { get; set; }
}
public class BasicQuery : Query<Result<ExampleDto>>
{
}
public class BasicQueryHandler : AbstractQueryHandler<BasicQuery, Result<ExampleDto>, ExampleDto>
{
public override Task<Result<ExampleDto>> HandleQuery(BasicQuery request)
{
return Task.FromResult(Result<ExampleDto>.Success(new ExampleDto() { Name = "Result Name" }));
}
}
And then the test:
[Fact]
public async Task GivenBasicQuery_whenHandle_thenSuccessResultWithPayload()
{
var handler = new BasicQueryHandler();
var result = await handler.Handle(new BasicQuery(), CancellationToken.None);
Check.That(result.IsSuccess).IsTrue();
Check.That(result.Payload.Name).IsEqualToValue("Result Name");
}
As you can see in the BasicQueryHandler there is some kind of duplication when declaring the three types, namely <BasicQuery, Result<ExampleDto>, ExampleDto>. It seems really fishy to me. I also tried many other possibilities, checking articles and SO questions/answers on the internet but could not come up with a cleaner solution with. What am I doing wrong? Is it possible to reduce the number of type parameters (of query handler) to 2? Thanks in advance for you help!
Basically, I moved the Result<> from the type parameter in the class declaration to the method declaration. I also removed the interfaces for clarity (you didn't share the definitions anyway).
public abstract class AbstractQueryHandler<TQuery, TQueryResult>
where TQuery : Query<TQueryResult>
where TQueryResult : class, new()
{
public Task<Result<TQueryResult>> Handle(TQuery request, CancellationToken cancellationToken)
{
try
{
return HandleQuery(request);
}
catch (Exception e)
{
return Task.FromResult(Result<TQueryResult>.Failure(new TQueryResult(), GetFailureMessage(e)));
}
}
public abstract Task<Result<TQueryResult>> HandleQuery(TQuery request);
private static string GetFailureMessage(Exception e)
{
return "There was an error while executing query: \r\n" + e.Message;
}
}
public class BasicQueryHandler : AbstractQueryHandler<BasicQuery, ExampleDto>
{
public override Task<Result<ExampleDto>> HandleQuery(BasicQuery request)
{
return Task.FromResult(Result<ExampleDto>.Success(new ExampleDto() { Name = "Result Name" }));
}
}
Note that since you need to new up a TQueryResult in the exception path, the new() keyword had to be added to the generic constraint.

IQueryable does not return Count property

public interface IRepository<T> : IDisposable
{
void Add(T newEntity);
void Delete(T entity);
T Find(int id);
IQueryable<T> FindAll();
int Commit();
}
public class SqlRepository<T> : IRepository<T> where T : class
{
DbContext context;
DbSet<T> set;
public SqlRepository(DbContext context)
{
this.context = context;
this.set = context.Set<T>();
}
public void Add(T newEntity)
{
this.set.Add(newEntity);
}
public void Delete(T entity)
{
}
public T Find(int id)
{
throw new Exception("todo");
}
public IQueryable<T> FindAll()
{
return this.set;
}
public int Commit()
{
return this.context.SaveChanges();
}
public void Dispose()
{
this.context.Dispose();
}
}
using (IRepository<Contact> e = new SqlRepository<Contact>(new AppointmentReminderDb()))
{
e.Add(new Contact() { Active = true });
e.Add(new Contact() { Active = true });
e.Commit();
var count = await e.FindAll().Count(); // do not get Count property
}
In the above line of code, I don't understand why I am not getting Count property. Instead I get CountAsynch. I really want to simply get Count property.
My IQueryable for FindAll is correctly defined in the interface and in the class method.
You may have forgotten to include the right namespace.
The method you're seeing in IntelliSense is named QueryableExtensions.CountAsync<TSource> defined in the System.Data.Entity namespace, which returns Task<int> and, as such, should be awaited.
The method (not property) you're looking for is named Queryable.Count<T>() and is defined in the System.Linq namespace. It returns an int and should not be awaited.
If the operation involves IO, which it probably does, you want to use CountAsync.

How do I use GraphDiff when DBContext is abstracted?

I have just learned about GraphDiff, and how it is supposed to take care of all the differences between the disconnected entity and the one stored in the database.
The thing is that I do not know how to use GraphDiff, I tried the documentation, but I didn't understand it well.
I am using an abstracted DBContext, through an Interface and using DbSet so I could perform Unit Testing on them:
public interface IDbRepositories
{
IDbSet<Client> ClientsDB { get;}
AppIdentityDbContext DB { get; }
IDbSet<Contacts> ContactsDB { get; }
IDbSet<ExposureResult> ExposureDB { get; }
IDbSet<OrderMods> OrderModsDB { get; }
IDbSet<ProductDetails> ProductDetailsDB { get; }
IDbSet<OrderProcess> OrderProcessDB { get; }
IDbSet<Order> OrderDB { get; }
void SaveChanges();
}
This is the actual class implementing the interface:
public class DbRepositories : IDbRepositories
{
private AppIdentityDbContext db = new AppIdentityDbContext();
//Get DB Context. This is done this way, so a Mock can be injected when testing
public IDbSet<Client> ClientsDB
{
get { return db.Clients; }
}
public AppIdentityDbContext DB
{
get { return db; }
}
public IDbSet<Contacts> ContactsDB
{
get { return db.Contacts; }
}
public IDbSet<ExposureResult> ExposureDB
{
get { return db.ExposureTBL; }
}
public IDbSet<OrderMods> OrderModsDB
{
get { return db.OrderMods; }
}
public IDbSet<ProductDetails> ProductDetailsDB
{
get { return db.ProductDetailsTBL; }
}
public IDbSet<OrderProcess> OrderProcessDB
{
get { return db.OrderProcesses; }
}
public IDbSet<Order> OrderDB
{
get { return db.OrderTBL; }
}
public void SaveChanges()
{
this.db.SaveChanges();
}
}
Now, the problem part is in here:
public bool SaveOrderChanges(OrderProcess[] Order, int OrderID, int uid)
{
//2nd Step:
var ComparableObject = dbs.OrderProcessDB.Where(x => x.OrderID == OrderID).ToList();
var Objections = dbs.OrderDB.Where(x => x.OrderID == OrderID).FirstOrDefault();
dbs.DB.UpdateGraph(dbs.OrderDB, m => m.OwnedCollection());
dbs.SaveChanges();
return true;
}
I'd like to tell the differences between the Order parameter and the one I extract from OrderProcessDB. These are a One to Many Relationship.
I do not know how to use GraphDiff for this scenario. Any ideas?
You could just expose the base DbContext object in the interface, but that would violate basic principles of encapsulation. The challenge is that the UpdateGraph method is a static extension off of the concrete DbContext class. Here is my solution:
First the interface:
public interface IMyDbContext
{
...
TEntity UpdateGraph<TEntity>(TEntity entity, Expression<Func<IUpdateConfiguration<TEntity>, object>> mapping = null) where TEntity : class, new();
}
Then the actual DbContext:
public class MyDbContext : DbContext, IMyDbContext
{
...
public TEntity UpdateGraph<TEntity>(TEntity entity, Expression<Func<IUpdateConfiguration<TEntity>, object>> mapping = null) where TEntity : class, new()
{
return ((DbContext)this).UpdateGraph(entity, mapping);
}
}
And lastly example usage inside of a repository:
public class MyRepository : IMyRepository
{
private readonly IMyDbContext _myDbContext;
public MyRepository (IMyDbContext myDbContext)
{
_myDbContext = myDbContext;
}
public async Task<SomeEntity> UpdateSomeEntity(SomeEntity updatedSomeEntity)
{
_myDbContext.UpdateGraph(updatedSomeEntity, map => map.OwnedCollection(p => p.SomeChildCollection));
await _myDbContext.SaveChangesAsync();
return updatedSomeEntity;
}
}
I realize this is old, but I just found out about GraphDiff and can hopefully help anyone else looking.
This is how you use GraphDiff:
db.UpdateGraph(orderToUpdate, map => map
.AssociatedCollection(t => t.Products)
.OwnedCollection(t => t.PaymentMethods));
This says to update the Order object, and that the Order owns the PaymentMethods (meaning it can actually remove those entities), and is associated with the Products entities (meaning it will remove them from the reference table).

How implement generic repository against mongodb?

I am new to mongodb and I am working on mvc4 web application for a new project.
I want to use repository pattern that will talk to a mongodb context for database level communications.
Simple interface that I have used with Entity Framework 4.0 is following. The find members are the problematic area for me. I don't have a clue how to proceed with them with mongodb context.
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();
}
I have a very simple model that is called Hero its drive from ImongoEntity which provides a member called 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 class is very simple you can see the collection of Heros exposted as IQueryable property.
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();
}
}
}
Now in my repository most simple methods are add and remove they successfully talk to mongodb context and get entities added or deleted from mongodb. Find method however gives me compiler level errors. I need help for my find and find all method. I am using genrics because I need my repositry class for enties like hero, solution, project, user and category.
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();
//}
}
If you are interested in an implementation similar to Rob Connery's and NBlog storage code but using the mongodb csharp driver 2.0 (that is asynchronous), you can look at:
https://github.com/alexandre-spieser/mongodb-generic-repository
You can then write a custom repository inheriting from 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);
}
}
Update: It is now available as its own nuget package:
Install-Package MongoDbGenericRepository
It looks like you're trying to use LINQ against your collections. That's perfect. You can do this much easier if you just expose an IQueryable property rather than write a Find() method.
Here's an example from you sample above:
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...
}
}
}
Of course, then when you consume this class, just do:
var r = new HeroRepository();
var heros = r.Heros.Where(r => r.SuperPowerLevel > 20);
Generic
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);
}
I know that It's a quite old post, but I would like to share with you the MongoRepository project implemented at Github or download as a NuGet package
Note: One of the problem that I had trying to implement the MongoDB Repository has been the different behaviour depending on the MongoDB driver version or wich is more or less the same, the .NET Framework. The MongoRepository project (in the link above) has solved this problem whith different code versions for .net 3.5, 4.0 and 4.5 frameworks that use different version of MongoDB driver (check MongoDB driver compatibility), wich has been very helpful.

Categories