L'idea è avere un unico repository generico che funzioni con tutte le entità. Ci sono riuscito, ma se ho bisogno di un metodo che dovrebbe includere una o più altre entità, c'è un problema per me. Ho messo qualche idea in codice, ma non funziona per me. Inoltre ho pensato di utilizzare la funzione di aggregazione in EF, ma che non ho mai usato. Qualcuno può darmi indicazioni su come posso gestirlo?
public interface IRepository<T> where T : BaseEntity
{
IEnumerable<T> GetAll();
T Get(Int64 id);
void Insert(T entity);
void Delete(T entity);
Task<bool> SaveChangesAsync();
T SearchByName(Expression<Func<T, bool>> predicate);
IEnumerable<T> GetAll(string[] includes);
}
public class Repository<T> : IRepository<T> where T : BaseEntity
{
private Entities.AppContext _context;
private DbSet<T> entities;
public Repository(Entities.AppContext context)
{
_context = context;
entities = _context.Set<T>();
}
public void Delete(T entity)
{
if (entity == null)
{
throw new ArgumentNullException("entity");
}
entities.Remove(entity);
}
public T Get(long id)
{
return entities.SingleOrDefault(s => s.Id == id);
}
public IEnumerable<T> GetAll()
{
return entities.ToList();
}
public IEnumerable<T> GetAll(string[] includes)
{
foreach (string include in includes)
{
entities.Include(include);
}
return entities;
}
public void Insert(T entity)
{
if (entity == null)
{
throw new ArgumentNullException("entity");
}
entities.Add(entity);
}
public async Task<bool> SaveChangesAsync()
{
try
{
return (await _context.SaveChangesAsync()) > 0;
}
catch (Exception ex)
{
return false;
}
}
public T SearchByName(Expression<Func<T, bool>> predicate)
{
return entities.Where(predicate).SingleOrDefault();
}
}
Sei caduto nella tipica trappola di chiamare un metodo che restituisce qualcosa e ignora il risultato. Le entities.Include(include);
linea entities.Include(include);
non fa nulla - simile alle entities.Where(...);
, entities.Select(...);
eccetera.
Il codice corretto è qualcosa del genere:
var query = entities.AsQueryable();
foreach (var include in includes)
query = query.Include(include);
return query;
o con linea singola Aggregate
:
return includes.Aggregate(entities.AsQueryable(), (query, path) => query.Include(path));