using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; namespace DbContextLib { public class GenericRepository where TEntity : class { private DbContext Context { get; set; } private DbSet Set { get; set; } public GenericRepository(DbContext context) { Context = context; Set = Context.Set(); } public virtual TEntity? GetById(object id) { return Context.Set().Find(id); } public virtual IEnumerable GetItems(Expression>? filter = null, int index = 0, int count = 10, params string[] includeProperties) => GetItems(filter, null, index, count, includeProperties); public virtual IEnumerable GetItems(Func, IOrderedQueryable>? orderBy = null, int index = 0, int count = 10, params string[] includeProperties) => GetItems(null, orderBy, index, count, includeProperties); public virtual IEnumerable GetItems(int index = 0, int count = 10, params string[] includeProperties) => GetItems(null, null, index, count, includeProperties); public virtual IEnumerable GetItems(Expression>? filter = null, Func, IOrderedQueryable>? orderBy = null, int index = 0, int count = 10, params string[] includeProperties) { IQueryable query = Set; if (filter != null) { query = query.Where(filter); } foreach (string includeProperty in includeProperties) { query = query.Include(includeProperty); } if (orderBy != null) { query = orderBy(query); } return query.Skip(index * count) .Take(count) .ToList(); } public virtual void Insert(TEntity entity) { var primaryKeyProperty = Context.Model.FindEntityType(typeof(TEntity)).FindPrimaryKey().Properties.FirstOrDefault(); if (primaryKeyProperty != null) { var parameter = Expression.Parameter(typeof(TEntity), "x"); var property = Expression.Property(parameter, primaryKeyProperty.Name); var idValue = Expression.Constant(primaryKeyProperty.GetGetter().GetClrValue(entity)); var equal = Expression.Equal(property, idValue); var lambda = Expression.Lambda>(equal, parameter); var existingEntity = Set.Local.FirstOrDefault(lambda.Compile()); if (existingEntity != null) { Set.Entry(existingEntity).Property("Count").CurrentValue = (int)Set.Entry(existingEntity).Property("Count").CurrentValue + 1; } else { Set.Add(entity); } } else { throw new InvalidOperationException("Cannot find primary key property for entity type."); } } public virtual void Insert(params TEntity[] entities) { foreach (var entity in entities) { Insert(entity); } } public virtual void Delete(object id) { TEntity? entity = Set.Find(id); if (entity == null) return; Delete(entity); } public virtual void Delete(TEntity entity) { var primaryKeyProperty = Context.Model.FindEntityType(typeof(TEntity)).FindPrimaryKey().Properties.FirstOrDefault(); if (primaryKeyProperty != null) { var parameter = Expression.Parameter(typeof(TEntity), "x"); var property = Expression.Property(parameter, primaryKeyProperty.Name); var idValue = Expression.Constant(primaryKeyProperty.GetGetter().GetClrValue(entity)); var equal = Expression.Equal(property, idValue); var lambda = Expression.Lambda>(equal, parameter); var existingEntity = Set.Local.FirstOrDefault(lambda.Compile()); if (existingEntity == null) { if (Context.Entry(entity).State == EntityState.Detached) { Set.Attach(entity); } Set.Remove(entity); } else { Set.Remove(existingEntity); } } else { throw new InvalidOperationException("Cannot find primary key property for entity type."); } } public virtual void Update(TEntity entity) { var primaryKeyProperty = Context.Model.FindEntityType(typeof(TEntity)).FindPrimaryKey().Properties.FirstOrDefault(); if (primaryKeyProperty != null) { var parameter = Expression.Parameter(typeof(TEntity), "x"); var property = Expression.Property(parameter, primaryKeyProperty.Name); var idValue = Expression.Constant(primaryKeyProperty.GetGetter().GetClrValue(entity)); var equal = Expression.Equal(property, idValue); var lambda = Expression.Lambda>(equal, parameter); var existingEntity = Set.Local.FirstOrDefault(lambda.Compile()); if (existingEntity != null) { Context.Entry(existingEntity).CurrentValues.SetValues(entity); } else { Set.Attach(entity); Context.Entry(entity).State = EntityState.Modified; } } else { throw new InvalidOperationException("Cannot find primary key property for entity type."); } } } }