Mocking using MOQ and generic types - c#

Method to unit test: GetUserInfo
Following is the class containing the method:
public class AccountService : IAccountService
{
IUnitOfWork _UnitOfWork;
public AccountService(IUnitOfWork unitOfWork)
{
_UnitOfWork = unitOfWork;
}
public UserInfo GetUserInfo(string userName, string password)
{
var userInfo = new UserInfo();
userInfo.UserType = UserType.Invalid;
// Statement of interest
var portalUser = _UnitOfWork.Repository<DvaPortalUser>().Query().Filter(t => t.Email == userName && t.Password == password).Get().FirstOrDefault();
//....Rest of the code is not included for clarity
}
}
The interface to mock IUnitOfWork:
public interface IUnitOfWork
{
void Dispose();
void Save();
void Dispose(bool disposing);
IRepository<T> Repository<T>() where T : class;
}
Repository Implementation:
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
public virtual RepositoryQuery<TEntity> Query()
{
var repositoryGetFluentHelper = new RepositoryQuery<TEntity>(this);
return repositoryGetFluentHelper;
}
internal IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>,
IOrderedQueryable<TEntity>> orderBy = null,
List<Expression<Func<TEntity, object>>>
includeProperties = null,
int? page = null,
int? pageSize = null)
{
IQueryable<TEntity> query = DbSet;
if (includeProperties != null)
includeProperties.ForEach(i => query.Include(i));
if (filter != null)
query = query.Where(filter);
if (orderBy != null)
query = orderBy(query);
if (page != null && pageSize != null)
query = query
.Skip((page.Value - 1)*pageSize.Value)
.Take(pageSize.Value);
return query.ToList();
}
}
RepositoryQuery Implementation:
public sealed class RepositoryQuery<TEntity> where TEntity : class
{
private readonly List<Expression<Func<TEntity, object>>> _includeProperties;
private readonly Repository<TEntity> _repository;
private Expression<Func<TEntity, bool>> _filter;
private Func<IQueryable<TEntity>,
IOrderedQueryable<TEntity>> _orderByQuerable;
private int? _page;
private int? _pageSize;
public RepositoryQuery(Repository<TEntity> repository)
{
_repository = repository;
_includeProperties = new List<Expression<Func<TEntity, object>>>();
}
public RepositoryQuery<TEntity> Filter(Expression<Func<TEntity, bool>> filter)
{
_filter = filter;
return this;
}
public IEnumerable<TEntity> Get()
{
return _repository.Get(
_filter,
_orderByQuerable, _includeProperties, _page, _pageSize);
}
}
Unit Test Method:
[TestMethod]
public void AccountService_GetUserInfo_SuccessfulLogin()
{
var _UnitOfWork = new Mock<IUnitOfWork>();
_AccountService = new AccountService(_UnitOfWork.Object);
_UnitOfWork.Setup(a => a.Repository<T>())).Returns(??); //How do I setup this statement?
_UnitOfWork.VerifyAll();
}
Question: How do I setup mock call for the statement _UnitOfWork.Repository()?

I dont know how your IRepository<T> is implemented, but i gues your Query method returns a IEnumerable<T> or a list.
internal interface IRepository<T>
{
IEnumerable<T> Query();
}
// your mock
_UnitOfWork.Setup(a => a.Repository<DvaPortalUser>())).Returns(() => new MyTestRepository());
1. Solution
Define a explicit implemtation of you repository.
// your implementation
public class MyTestRepository : IRepository<DvaPortalUser>
{
public IEnumerable<DvaPortalUser> Query()
{
// return some test users (mocks)
return new List<DvaPortalUser> {new DvaPortalUser(), new DvaPortalUser()};
}
}
2. Solution (thanks to Yuliam Chandra)
Define a mock instead of the implemtation
var repository = new Mock<IRepository<DvaPortalUser>>();
// return some test users (mocks)
repository.Setup(a => a.Query()).Returns(new[] { new DvaPortalUser() });
_UnitOfWork.Setup(a => a.Repository<DvaPortalUser>()).Returns(repository.Object);
What you choose depends on your solution.

Related

how to inherit from generic repository without needing to implement all the members

Im trying to create a generic repository ,here is my IGenericRepository:
public interface IGenericRepository<TEntity> where TEntity : class
{
Task<IEnumerable<TEntity>> FindByFilterAsync(Expression<Func<TEntity, bool>> predicate, params Expression<Func<TEntity, object>>[] including);
Task<TEntity> GetByIdAsync(int id);
Task<bool> InsertAsync(TEntity obj);
}
here is the implementation of the respository:
public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class
{
private readonly IServiceScopeFactory scopeFactory;
public GenericRepository(IServiceScopeFactory scopeFactory) => this.scopeFactory = scopeFactory;
public async Task<IEnumerable<TEntity>> FindByFilterAsync(Expression<Func<TEntity, bool>> predicate, params Expression<Func<TEntity, object>>[] including)
{
using (var scope = this.scopeFactory.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<CleanArchitectureContext>();
var x = db.Set<TEntity>().AsQueryable();
if (including != null)
{
including.ToList().ForEach(s =>
{
if (s != null)
{
x = x.Include(s);
}
});
}
return await x.Where(predicate).ToListAsync().ConfigureAwait(true);
}
}
public Task<TEntity> GetByIdAsync(int id)
{
throw new NotImplementedException();
}
public Task<bool> InsertAsync(TEntity obj)
{
throw new NotImplementedException();
}
}
now lets say i need to have an interface which is going to inherit from the IGeneric repository and store data in the db:
public interface IStorePayoutRepository:IGenericRepository<PayoutModel>
{
}
so far so good, the problem is if i want to have a class and inherit from IStorePayoutRepository,then i need to implement all the members inside that which is not what i want,because i need only the store one(save or insert into db),
public class PayoutRepository : IGenericRepository<PayoutEntity>
{
//Im forced to implement all the members inside generic interface
}
as you see its not very optimal to implement all the members everytime as they could be irrelevant to the usecase,whats the right way here?i appreciate your help

Verifying service calls IRepository method that is defined in IGenericRepository

I have a service let's say Foo service class.
public class FooService : IFooService
{
private readonly IFooRepository _repository;
private readonly ISomeService _eventService;
public FooService(IFooRepository repository, ISomeService eventService)
{
_repository = repository;
_someService = someService;
}
public IReadOnlyCollection<Foo> GetFoos(bool isDeleted = true)
{
var foos= _repository.GetList(x => x.IsDeleted == isDeleted).ToList();
return !foos.Any() ? new List<Foo>(): foos;
}
}
Here is IFooRepository
public interface IFooRepository : IGenericRepository<Foo>
{
}
and here is IGenericRepository
public interface IGenericRepository<T> where T: BaseEntity
{
IReadOnlyCollection<T> GetList(Expression<Func<T, bool>> where, params Expression<Func<T, object>>[] nav);
}
In my test I want to verify that FooService's GetFoos method calls GetList method
This is what I tried
[TestClass]
public class FooServiceTest
{
private IQueryable<Foo> _foos;
private Mock<IFooRepository> _fooRepository;
private FooService _fooService;
private Mock<ISomeService> _someService;
[TestInitialize]
public void SetUp()
{
_foos = new List<Foo>
{
new Foo
{
EmailId = "a#a.com",
IsDeleted = false,
},
new Foo
{
EmailId = "a#a.com",
IsDeleted = true,
},
}.AsQueryable();
}
[TestMethod]
public void GetGetFoos_CallsGetList()
{
//Arrange
var foos= _foos.Where(x => x.IsDeleted).ToList();
_fooRepository = new Mock<IFooRepository>();
_fooRepository.Setup(m => m.GetList(x => x.IsDeleted)).Returns(foos);
_someServiceMock = new Mock<ISomeService>();
_fooService = new FooService(_fooRepository.Object, _someServiceMock.Object);
//Act
_fooService.GetFoos(true);
//Assert
_fooRepository.Verify(m=>m.GetList(x=>x.IsDeleted), Times.Once());
}
}
But I get argument null exception in following line
var foos= _repository.GetList(x => x.IsDeleted == isDeleted).ToList();
Any clue why this is happening even though I am saying Returns(foos) during setup.
Also how do I verify the interface method was called?
What is happening (most likely) is Moq can't match Expression<Func<T, bool>> when you do the .Setup().
So instead you can use IsAny<>() approach:
_fooRepository.Setup(m => m.GetList(It.IsAny<Expression<Func<Foo, bool>>>())).Returns(foos);
If you want to assert what expression is passed in, try
Expression<Func<Foo, bool>> capturedExpression = null;
_fooRepository.Setup(m => m.GetList(It.IsAny<Expression<Func<Foo, bool>>>()))
.Returns((Expression<Func<Foo, bool>> e ) => { capturedExpression = e; return foos; });
Assert.IsTrue(capturedExpression.Compile()(_foos[1]));
Assert.IsFalse(capturedExpression.Compile()(_foos[0]));
to verify the method was called you can also change the last it a bit more:
_fooRepository.Setup(m => m.GetList(It.IsAny<Expression<Func<Foo, bool>>>()))
.Returns((Expression<Func<Foo, bool>> e ) => { capturedExpression = e; return foos; })
.Verifiable();
then _fooRepository.Verify(m=>m.GetList(It.IsAny<Expression<Func<Foo, bool>>>()), Times.Once()); However, if it is not called, then capturedExpression is null (that technique is known as implicit assertion)

How can I mock the Set <entity> method of DbContext? [duplicate]

This question already has answers here:
Moq DbSet NotImplementedException
(2 answers)
Closed 5 years ago.
I want to do unit tests for that generic repository pattern, I have tried it in various ways and I can not get it, the closest thing to do is this here I leave the implementation that I have done
public abstract class Repository<TEntity, TKey> : IRepository<TEntity, TKey> where TEntity : Entity<TKey>
{
private readonly ValcalContext _context;
private readonly IUnitOfWork _unitOfWork;
public IUnitOfWork UnitOfWork => _unitOfWork;
public Repository(IUnitOfWork uow)
{
_context = uow.Context as ValcalContext;
_unitOfWork = uow;
}
public List<TEntity> All => _context.Set<TEntity>().ToList();
public List<TEntity> AllEager(params Expression<Func<TEntity, object>>[] includes)
{
IQueryable<TEntity> query = _context.Set<TEntity>();
foreach (var include in includes)
{
query = query.Include(include);
}
return query.ToList();
}
public TEntity Find(TKey id)
{
return _context.Set<TEntity>().Find(id);
}
public IEnumerable<TEntity> GetAll()
{
return _context.Set<TEntity>().ToList();
}
public void Insert(TEntity item)
{
_context.Entry(item).State = EntityState.Added;
}
public void Delete(TEntity entity)
{
var item = _context.Set<TEntity>().Find(entity.Id);
_context.Set<TEntity>().Remove(item);
}
public void Delete(TKey id)
{
var item = _context.Set<TEntity>().Find(id);
_context.Set<TEntity>().Remove(item);
}
public void Update(TEntity item)
{
_context.Set<TEntity>().Attach(item);
_context.Entry(item).State = EntityState.Modified;
}
public void Dispose()
{
if (_context != null)
_context.Dispose();
}
}
This is my dbContext
public class ValcalContext : DbContext,IValcalContext
{
public ValcalContext() : base("ValcalConnection")
{
}
public static ValcalContext Create()
{
return new ValcalContext();
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
AddConventions(modelBuilder);
var typesToRegister = TypesToRegister();
AddConfigurationsMapping(modelBuilder, typesToRegister);
base.OnModelCreating(modelBuilder);
}
#region Private Methods
/// <summary>
/// /Agrega las convenciones de mapeo a la base de dato
/// </summary>
/// <param name="modelBuilder"></param>
private void AddConventions(DbModelBuilder modelBuilder)
{
modelBuilder.Types().Configure(entity => entity.ToTable(entity.ClrType.Name.ToLowerUnderscored()));
modelBuilder.Conventions.Add(new UnderScoredLowerCaseConvention());
}
private static IEnumerable<Type> TypesToRegister()
{
var typesToRegister = Assembly.GetExecutingAssembly().GetTypes()
.Where(type => !string.IsNullOrEmpty(type.Namespace))
.Where(type => type.BaseType != null && type.BaseType.IsGenericType
&& type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
return typesToRegister;
}
private static void AddConfigurationsMapping(DbModelBuilder modelBuilder, IEnumerable<Type> typesToRegister)
{
foreach (var configurationInstance in typesToRegister.Select(Activator.CreateInstance))
{
modelBuilder.Configurations.Add((dynamic)configurationInstance);
}
}
#endregion
}
I want to do unit tests for that generic repository pattern,for now I have this
[TestClass]
public class RepositoryUnitTest
{
[TestMethod]
public void Sample()
{
//arrange
var mockEntityTest = new Mock<DbSet<EntityTest>>();
var unitOfWork = new Mock<IUnitOfWork>();
var valcalContext = new Mock<ValcalContext>();
valcalContext.Setup(vc => vc.Set<EntityTest>()).Returns(mockEntityTest.Object);
var mock = valcalContext.Object;
unitOfWork.Setup(uow => uow.Context).Returns(mock);
var repository = new RepositoryTest(unitOfWork.Object);
//act
var entityTests = repository.All;
//assert
Assert.AreEqual(entityTests.ToList().Count,0);
}
}
public class RepositoryTest : Repository<EntityTest, int>
{
public RepositoryTest(IUnitOfWork uow) : base(uow)
{
}
}
public class EntityTest : Entity<int>
{
}
but I get this error
I hope you can help me, I've been here for two hours
The member 'IEnumerable.GetEnumerator' has not been
implemented on type 'DbSet1Proxy' which inherits from 'DbSet1'. Test
doubles for 'DbSet`1' must provide implementations of methods and
properties that are used.
This error is different from this post Moq DbSet NotImplementedException
I just tried that solution and I'm still in the same
Really what I did was the following to make it clear
I uploaded the moq version for 4.8
I change this
[TestMethod]
public void Sample()
{
//arrange
var mockEntityTest = new Mock<DbSet<EntityTest>>();
var unitOfWork = new Mock<IUnitOfWork>();
var valcalContext = new Mock<ValcalContext>();
valcalContext.Setup(vc => vc.Set<EntityTest>()).Returns(mockEntityTest.Object);
var mock = valcalContext.Object;
unitOfWork.Setup(uow => uow.Context).Returns(mock);
var repository = new RepositoryTest(unitOfWork.Object);
//act
var entityTests = repository.All;
//assert
Assert.AreEqual(entityTests.ToList().Count,0);
}
for this
[TestMethod]
public void Sample()
{
//arrange
var mockEntityTest = new Mock<DbSet<EntityTest>>();
var list = new List<EntityTest>();
var queryable = list.AsQueryable();
mockEntityTest.As<IQueryable<EntityTest>>().Setup(m => m.Provider).Returns(queryable.Provider);
mockEntityTest.As<IQueryable<EntityTest>>().Setup(m => m.Expression).Returns(queryable.Expression);
mockEntityTest.As<IQueryable<EntityTest>>().Setup(m => m.ElementType).Returns(queryable.ElementType);
mockEntityTest.As<IQueryable<EntityTest>>().Setup(m => m.GetEnumerator()).Returns(() => queryable.GetEnumerator());
var unitOfWork = new Mock<IUnitOfWork>();
var valcalContext = new Mock<ValcalContext>();
valcalContext.Setup(vc => vc.Set<EntityTest>()).Returns(mockEntityTest.Object);
var mock = valcalContext.Object;
unitOfWork.Setup(uow => uow.Context).Returns(mock);
var repository = new RepositoryTest(unitOfWork.Object);
//act
var entityTests = repository.All;
//assert
Assert.AreEqual(entityTests.ToList().Count,0);
}
and it worked, that can be done generically as explained in this post How do I go about unit testing with Entity Framework and Moq? 45558663 # 45558663
but the essence of what I did was that.

How do I mock these classes using moq

Please can someone show me how to properly mock this repository class. Basically I want to just mock out it so that I can easily test my services layer. Am moq using c# moq in my test project. Where am mostly having problems is in the virtual interface pattern used in the Query, Filter, Include and OrderBy methods. How do I mock it so that it can return the properly RepositoryQuery that I injected into my Repository mock.
The code shown below is part of my database layer that communicates with the database, so I want to mock it out so that I can easily test my services layer without external dependence to worry about.
public sealed class RepositoryQuery<TEntity> : IRepositoryQuery<TEntity> where TEntity : BaseEntity
{
private readonly List<Expression<Func<TEntity, object>>> _includeProperties;
private readonly Repository<TEntity> _repository;
private readonly List<Expression<Func<TEntity, bool>>> _filters;
private Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> _orderByQuerable;
private int? _page;
private int? _pageSize;
public RepositoryQuery(Repository<TEntity> repository)
{
_repository = repository;
_includeProperties = new List<Expression<Func<TEntity, object>>>();
_filters = new List<Expression<Func<TEntity, bool>>>();
}
public RepositoryQuery<TEntity> Filter(Expression<Func<TEntity, bool>> filter)
{
_filters.Add(filter);
return this;
}
public RepositoryQuery<TEntity> OrderBy(Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy)
{
_orderByQuerable = orderBy;
return this;
}
public RepositoryQuery<TEntity> Include(Expression<Func<TEntity, object>> expression)
{
_includeProperties.Add(expression);
return this;
}
public IQueryable<TEntity> Get()
{
return _repository.Get(_filters, _orderByQuerable, _includeProperties, _page, _pageSize);
}
}
and this
public class Repository<TEntity> : IRepository<TEntity> where TEntity : BaseEntity
{
private readonly Guid _instanceId;
private readonly DbSet<TEntity> _dbSet;
private readonly IDbContext _context;
public Repository(IDbContext context)
{
_context = context;
_dbSet = context.Set<TEntity>();
_instanceId = Guid.NewGuid();
}
public virtual IRepositoryQuery<TEntity> Query()
{
var repositoryGetFluentHelper = new RepositoryQuery<TEntity>(this);
return repositoryGetFluentHelper;
}
internal IQueryable<TEntity> Get(
List<Expression<Func<TEntity, bool>>> filters = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
List<Expression<Func<TEntity, object>>> includeProperties = null,
int? page = null,
int? pageSize = null)
{
IQueryable<TEntity> query = _dbSet;
if (includeProperties != null)
{
includeProperties.ForEach(i => query = query.Include(i));
}
if (filters != null && filters.Any())
{
query = filters.Aggregate(query, (current, filter) => current.Where(filter));
}
query = orderBy != null ? orderBy(query) : query.OrderBy(a => a.Id);
if (page != null && pageSize != null)
{
query = query
.Skip((page.Value - 1)*pageSize.Value)
.Take(pageSize.Value);
}
return query;
}
}
Hopefully your components depend on the interfaces IRepositoryQuery<TEntity> and IRepository<TEntity> and not the concrete implementations RepositoryQuery<TEntity> and Repository<TEntity>. If that is the case, then you provide test doubles for the interfaces for unit test purposes with Moq like so
var mockQuery = new Mock<IRepositoryQuery<TEntity>>();
// perform any setup needed on mockQuery for the particular System Under Test
var mockRepository = new Mock<IRepository<TEntity>>();
// perform any setup needed on mockRepository for the particular System Under Test
// component that relies on query and repository
// that is the System Under Test i.e. the focus of the unit test
var systemUnderTest = new SystemUnderTest(mockRepository.Object, mockQuery.Object);
An observation; Looking at RepositoryQuery<TEntity>, I think the methods should return the interface IRepositoryQuery<TEntity> as opposed to the concrete implementation RepositoryQuery<TEntity>.
If IRepositoryQuery is the wrapper for IRepository, then - to test your service layer - you don't need to mock IRepository. Just mock IRepositoryQuery.
Assuming that I want to check that SomeService.DoSomething correctly processes the result it gets from IRepositoryQuery.Get:
var mock = new Mock<IRepositoryQuery<SomeClass>>();
mock.Setup(o => o.Get(/* test parameters */)).Returns(/* result */);
var myService = new SomeService(mock.Object);
Assert.That(myService.DoSomething(), Is.EqualTo(/* expected result*/));

Implementing IDbSet in Generic Repository

I have followed this tutorial and already implemented in my project.
I made some changes to make more testable, so I implement interface
public class GenericRepository<T> : IGenericRepository<T> where T : class
{
internal MyEntities context;
internal IDbSet<T> dbSet;
public virtual IEnumerable<TEntity> GetWithRawSql(string query, params object[] parameters)
{
return dbSet.SqlQuery(query, parameters).ToList();
}
...
}
public interface IEmployeeRepository : IGenericRepository<Employee> { }
public class EmployeeRepository : GenericRepository<Employee>, IEmployeeRepository { }
in UnitOfWork:
public class UnitOfWork : IDisposable
{
private MyEntities context = new MyEntities();
private IEmployeeRepository employeeRepository;
public IEmployeeRepository EmployeeRepository
{
get { return employeeRepository ?? (employeeRepository = new EmployeeRepository(context)); }
}
}
Then I cannot access dbSet in GetWithRawSql() because I change to IDbSet.
(1) How to solve this?
(2) Is there any better approach (without dbSet) to this code using the above approach as this is also failed because IDbSet
unitOfWork.EmployeeRepository.dbSet.Select(c => new {
EmpID = c.EmployeeID,
FullName = (c.LastName + ", " + c.FirstName)
}).OrderBy(o => o.FullName);
Thanks.
i believe that this is a poor implementatin, here is the one im currently using:
this is going to be your IRepository
public interface IRepository<T> where T : class, IEntity
{
void Add(T item);
void Remove(T item);
void Update(T item);
void Attach(T item);
IQueryable<T> All<TProperty>(params Expression<Func<T, TProperty>>[] path);
IQueryable<T> All(params string[] path);
T Find(object id);
T First(Expression<Func<T, bool>> predicate, params string[] path);
Task<T> FirstAsync(Expression<Func<T, bool>> predicate, params string[] path);
T First<TProperty>(Expression<Func<T, bool>> predicate, params Expression<Func<T, TProperty>>[] path);
IQueryable<T> Where<TProperty>(Expression<Func<T, bool>> predicate, params Expression<Func<T, TProperty>>[] path);
IQueryable<T> Where(Expression<Func<T, bool>> predicate, params string[] includes);
}
often you need to attach entities to context so i added Attach method but if you want to keep entity framework attach Seperate (witch is not really needed) from regular IRepository you can define a new interface and called ISqlRepository and inherit from IRepository, creating two IRepository will just make it more complex since it dosnt make any problem in UnitTest. any way if you do want to seperate this is going to be your ISqlRespository:
public interface ISqlRepository<T>: IRepository<T> where T:class, IEntity
{
void Update(T item);
void Attach(T item);
}
this is unitOfWork interface:
public interface IUnitOfWork<T> where T : class, IEntity
{
IRepository<T> Repistory { get; }
IRepository<TEntity> GetTypeRepository<TEntity>() where TEntity : class, IEntity;
object GetContext();
int Commit();
Task<int> CommitAsync();
}
and finally concrete implementation (without ISqlRepository since i dont use that):
this is implementation of IRespository:
public class SqlRepository<T>: IRepository<T> where T: class, IEntity
{
protected readonly DbSet<T> _objectSet;
protected ApplicationDbContext _context;
public SqlRepository(ApplicationDbContext context)
{
_objectSet = context.Set<T>();
this._context = context;
}
public void Add(T item)
{
_objectSet.Add(item);
}
public void Update(T item)
{
_context.Entry(item).State = EntityState.Modified;
}
public void Remove(T item)
{
_objectSet.Remove(item);
}
public T First(Expression<Func<T, bool>> predicate, params string[] path)
{
IQueryable<T> query = _objectSet;
if (path != null)
{
path.ForeEach(i => query = query.Include(i));
}
return query.FirstOrDefault(predicate);
}
public T First<TProperty>(Expression<Func<T, bool>> predicate, params Expression<Func<T, TProperty>>[] path)
{
IQueryable<T> query = _objectSet;
path.ForeEach(p => query = query.Include(p));
return query.First(predicate);
}
public IQueryable<T> Where<TProperty>(Expression<Func<T, bool>> predicate, params Expression<Func<T, TProperty>>[] path)
{
IQueryable<T> query = _objectSet;
path.ForeEach(p => query = query.Include(p));
return query.Where(predicate);
}
public IQueryable<T> Where(Expression<Func<T, bool>> predicate, params string[] includes)
{
IQueryable<T> query = _objectSet;
includes.ForeEach(i => query = query.Include(i));
return query.Where(predicate);
}
public IQueryable<T> All<TProperty>(params Expression<Func<T, TProperty>>[] path)
{
IQueryable<T> query = _objectSet;
if (path != null)
{
path.ForeEach(p => query.Include(p));
}
return query;
}
public IQueryable<T> All(params string[] path)
{
IQueryable<T> query = _objectSet;
if (path != null)
{
path.ForeEach(p => query = query.Include(p));
}
return query;
}
public T Find(object id)
{
return _objectSet.Find(id);
}
public void Attach(T item)
{
T old = _objectSet.Local.FirstOrDefault(i => i.Id == item.Id);
if (old != null)
{
_context.Entry<T>(old).State = EntityState.Detached;
}
_objectSet.Attach(item);
}
public System.Threading.Tasks.Task<T> FirstAsync(Expression<Func<T, bool>> predicate, params string[] path)
{
IQueryable<T> query = _objectSet;
if(path != null)
{
path.ForeEach(i => query = query.Include(i));
}
return query.FirstOrDefaultAsync(predicate);
}
}
this the unitOfWork:
public class SqlUnitOfWork<T> : IUnitOfWork<T> where T : class, IEntity
{
private ApplicationDbContext _db;
public SqlUnitOfWork(ApplicationDbContext context)
{
_db = context;
}
public IRepository<T> Repistory
{
get
{
return new SqlRepository<T>(_db);
}
}
public int Commit()
{
return _db.SaveChanges();
}
public Task<int> CommitAsync()
{
return _db.SaveChangesAsync();
}
public object GetContext()
{
return this._db;
}
public IRepository<TEntity> GetTypeRepository<TEntity>() where TEntity : class, IEntity
{
return new SqlRepository<TEntity>(_db);
}
}

Categories