IQueryable does not return Count property - c#

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.

Related

The provider for the source IQueryable doesn't implement IAsyncQueryProvider

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

Data is not saving in db using generic repository and Entity Framework 5.0

I've created application asp.net using a generic repository and Entity Framework.
The abstract class has this code:
public interface IGenericRepository<T> where T : class
{
IQueryable<T> GetAll();
IQueryable<T> FindBy(Expression<Func<T, bool>> predicate);
void Add(T entity);
void Delete(T entity);
void Edit(T entity);
void Save();
}
and the GenericRepository class contains the following code:
public abstract class GenericRepository<C, T> : IGenericRepository<T> where T : class where C : DbContext, new()
{
private C _entities = new C();
public C Context {
get { return _entities; }
set { _entities = value; }
}
public virtual IQueryable<T> GetAll() {
IQueryable<T> query = _entities.Set<T>();
return query;
}
public IQueryable<T> FindBy(System.Linq.Expressions.Expression<Func<T, bool>> predicate) {
IQueryable<T> query = _entities.Set<T>().Where(predicate);
return query;
}
public virtual void Add(T entity) {
_entities.Set<T>().Add(entity);
}
public virtual void Delete(T entity) {
_entities.Set<T>().Remove(entity);
}
public virtual void Edit(T entity) {
_entities.Entry(entity).State = System.Data.EntityState.Modified;
}
public virtual void Save() {
_entities.SaveChanges();
}
}
Now I want to create class for each of my database tables to save the data.
Here is the code for one of my database tables:
public class AmountDLL : GenericRepository<HMSEntities, Tbl_Amount>
{
//:Base<Tbl_Amount>
public override void Add(Tbl_Amount entity)
{
base.Add(entity);
}
}
At last I have tried to add data through front end on button click
protected void btnsave_Click(object sender, EventArgs e)
{
AmountDLL amtdll = new AmountDLL();
Tbl_Amount tblamt = new Tbl_Amount();
tblamt.Amt_Type = txt_amt_type.Text;
tblamt.UserId = User.Identity.GetUserId();
if (CheckBox1.Checked == true)
{
tblamt.IsActive = true;
}
else
{
tblamt.IsActive = false;
}
amtdll.Add(tblamt);
}
When I run the application, it worked fine, but it did not save the data in the table.
Please check and suggest any changes
In Entity Framework for every entity to save the data either it's insert, update or delete, we call the SaveChanges() on instance of that entity.
In your case you need to call the Save() method for persisting to database which you have defined in your repository class for that which abstracts the SaveChanges() call to your respective Entity type:
amtdll.Add(tblamt);
amtdll.Save(); // this needs to be called.

Task<TEntity> preferred way to do repository

public async Task<TEntity> GetByIdAsync(int id) {
return await Context.FindByAsync(id);
}
and
public IQueryable<TEntity> GetById(Expression<Func<TEntity, int>> predicate) {
return Context.Where(predicate).FirstOrDefault;
}
I'm new to repositories and looking for tutorials and now kinda know what it does but the Task struck me. Between the two which is more preferred? I know it's a stupid question but it would help me understand them better. Any help would be much appreciated. Thanks!
First to your question:
GetByIdAsync: is used to load the data asynchrone from the database, If you have a lot of data for example you have to load about 10000 entries from database then this method it will be the right choice(You can also use bulk operation).
GetById: synchrone load the data from the DB this method is good if your query take just a few milliseconds and does not be called a lot of times from the same thread.
How to use them:
var employee= await new EmployeeRepository.GetByIdAsync(1);---> your method(caller) must be here also Async otherwise, you have to use task.
var employee= new EmployeeRepository.GetById(1);
If your Repository class return IQueryable then you have to do ToList.First();
You need Entity framework 6 or later =>> support of Async.,
otherwise you have to do it by your self!
Example: Let say your business object:
public class Employee
{
public int Id { get; set; }
public string FullName { get; set; }
}
// Now using this we will have a simple context class.
public class HRContext : DbContext
{
public DbSet<DomainClasses.Employee> Employees { get; set; }
}
// After that, define the repository interface IEmployeeRepository.
public interface IEmployeeRepository : IDisposable
{
IQueryable<Employee> All { get; }
IQueryable<Employee> AllAsync { get; }
IQueryable<Employee> AllIncluding(params Expression<Func<Employee, object>>[] includeProperties);
Employee Find(int id);
Employee FindAsync(int id);
void InsertOrUpdate(Employee employee);
void Delete(int id);
void Save();
}
// Then the Repository class called EmployeeRepository.
public class EmployeeRepository : IEmployeeRepository
{
HRContext context = new HRContext();
public IQueryable<Employee> All
{
get { return context.Employees; }
}
public IQueryable<Employee> AllIncluding(params Expression<Func<Employee, object>>[] includeProperties)
{
IQueryable<Employee> query = context.Employees;
foreach (var includeProperty in includeProperties)
{
query = query.Include(includeProperty);
}
return query;
}
public Employee Find(int id)
{
return context.Employees.Find(id);
}
public void InsertOrUpdate(Employee employee)
{
if (employee.Id == default(int)) {
// New entity
context.Employees.Add(employee);
} else {
// Existing entity
context.Entry(employee).State = EntityState.Modified;
}
}
public void Delete(int id)
{
var employee = context.Employees.Find(id);
context.Employees.Remove(employee);
}
public void Save()
{
context.SaveChanges();
}
public void Dispose()
{
context.Dispose();
}
}
I get the soruce code from :
http://blogs.msdn.com/b/wriju/archive/2013/08/23/using-repository-pattern-in-entity-framework.aspx
For example for a generic repository:
public interface IGenericRepository<T> where T : class {
IQueryable<T> GetAll();
IQueryable<T> GetAllAsync();
IQueryable<T> FindBy(Expression<Func<T, bool>> predicate);
IQueryable<T> FindByAsync(Expression<Func<T, bool>> predicate);
void Add(T entity);
void Delete(T entity);
void Edit(T entity);
void Save();
}
Where T is the base entity for all your entities.
here is the complete generic example:
http://www.tugberkugurlu.com/archive/generic-repository-pattern-entity-framework-asp-net-mvc-and-unit-testing-triangle
For better separation of concern you can also combine the repository pattern with unit of work as described by Martin Fowler book:
http://martinfowler.com/eaaCatalog/unitOfWork.html
Those two pieces of code do different things.
First piece finds a single entity.
var user = await new Repo<User>.GetByIdAsync(12);
Second piece executes the where clause and returns the first element or null. It is badly named because it does not actually force searching by Id.
var user = new Repo<User>.GetById(u => u.Username=="Bob");
The task is there to support .NET 4.5 await and async commands.

C# database abstraction class with Entity Framework

I want to create a common database abstraction in order to expose the same interface without worrying about the type of the DbContext that the database manage.
Here there is an example in order to explain well the concept:
public interface IDatabase<T> where T : DbContext {
void Add<T>(T entity);
void Remove<T>(T entity);
void SaveChanges();
}
The implementation can be:
public MyDatabase<T> : IDatabase<T> where T : MyContext {
public T Context { get; private set; }
//singleton contructor ...
public void Add<TC>(TC entity) {
Context.Set<TC>().Add(entity);
}
public void Remove<TC>(TC entity) {
Context.Set<TC>().Add(entity);
}
public void SaveChanges {
Context.SaveChanges();
}
}
The goals of this design are different: expose the same interface in order to decouple logic from database, change quickly the database (context), create one time the context and reuse during all the application lifetime (lock mechanism are required).
The problem is that the interface hides all the types of the sets in the context.
Context.Set<TC>().Add(entity); //this line don't compile
I'm not sure that this design is the best practise. How can I implement a design that offers these features?
Why you does not use the standard pattern for example Repository pattern you can also combine it with UnitOfWork.
You make it complicated for your self, just check this.
public interface IMyClassRepository : IDisposable
{
IQueryable<MyClass> All { get; }
IQueryable<MyClass> AllIncluding(params Expression<Func<MyClass, object>>[] includeProperties);
MyClass Find(int id);
void InsertOrUpdate(MyClass myClass);
void Delete(int id);
void Save();
}
public class MyClassRepository : IMyClassRepository
{
DBContext context = new DBContext();
public IQueryable<MyClass> All
{
get { return context.Employees; }
}
public IQueryable<MyClass> AllIncluding(params Expression<Func<MyClass, object>>[] includeProperties)
{
IQueryable<MyClass> query = context.MyClasses;
foreach (var includeProperty in includeProperties)
{
query = query.Include(includeProperty);
}
return query;
}
public MyClass Find(int id)
{
return context.MyClasses.Find(id);
}
public void InsertOrUpdate(MyClass myClass)
{
if (myClass.Id == default(int))
{
// New entity
context.MyClasses.Add(myClass);
}
else
{
// Existing entity
context.Entry(myClass).State = EntityState.Modified;
}
}
public void Delete(int id)
{
var employee = context.Employees.Find(id);
context.Employees.Remove(employee);
}
public void Save()
{
context.SaveChanges();
}
public void Dispose()
{
context.Dispose();
}
}
public class MyClass
{
}

integration testing for entity framework to ensure associations are correct

I guess this is more of an integration test, but does anyone have a link to a good tutorial on how to test to ensure the associations in your entity framework (4) model are working as expected?
My thought was to use something like sqllite for this, because I want to make sure I can save an entity, and add a child entity and persist that also etc.
If you are using code first, you could use a mocking framework to test your implementation.
As for the IDbSet instances that you can use there, the following was usefull:
public class InMemoryDbSet<T> : IDbSet<T> where T : class
{
private readonly HashSet<T> _data;
private readonly IQueryable _query;
public Type ElementType
{
get
{
return this._query.ElementType;
}
}
public Expression Expression
{
get
{
return this._query.Expression;
}
}
public IQueryProvider Provider
{
get
{
return this._query.Provider;
}
}
public InMemoryDbSet()
{
this._data = new HashSet<T>();
this._query = _data.AsQueryable();
}
public T Add(T entity)
{
this._data.Add(entity);
return entity;
}
public T Attach(T entity)
{
this._data.Add(entity);
return entity;
}
public TDerivedEntity Create<TDerivedEntity>() where TDerivedEntity : class, T
{
throw new NotImplementedException();
}
public T Create()
{
return Activator.CreateInstance<T>();
}
public virtual T Find(params Object[] keyValues)
{
throw new NotImplementedException("Derive from FakeDbSet and override Find");
}
public System.Collections.ObjectModel.ObservableCollection<T> Local
{
get
{
return new System.Collections.ObjectModel.ObservableCollection<T>(_data);
}
}
public T Remove(T entity)
{
this._data.Remove(entity);
return entity;
}
public IEnumerator<T> GetEnumerator()
{
return this._data.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this._data.GetEnumerator();
}
}
Using that approach should enable you to run your test completely in memory without the need to hit a database, but, as i said, only in code first because as far as i know, IDbContext is only used there.

Categories