J'essaie d'écrire un référentiel générique pour mon application Entity Framework. Voici mon code prototype:Création d'un référentiel générique pour une application Entity Framework
Interface
public interface IDomainRepository
{
T GetById<T>(int id, Expression<Action<T>> idx)
}
et le dépôt:
public class DomainRepository : IDomainRepository
{
private readonly DatabaseDataContext _ctx;
public DomainRepository(DatabaseDataContext ctx)
{
_ctx = ctx;
}
public T GetById<T>(int id, Expression<Action<T>> idx)
{
return _ctx.GetTable(typeof (T)).SingleOrDefault(idx);
}
}
Le code de test ci-dessus est ce qui ne fonctionne pas. Mais ce que je voudrais être en mesure de faire est la suivante:
var repository = new DomainRepository(myContext);
var client = repository.GetById<tbl_Clients>(23, c => c.clientId);
Donc, fondamentalement, je veux obtenir une entité client de la base de données en passant dans l'id plus un lambda dire GetById
ce que la colonne id est. En outre, je n'ai aucune idée de la façon dont j'exécuterais le lambda en utilisant l'identifiant passé.
Quelqu'un peut-il m'aider?
EDIT:
Je suis vraiment proche. J'ai changé GetById
:
public T GetById<T>(int id, Expression<Func<T, object>> idx)
et je peux maintenant l'appeler comme ceci:
var g = repository.GetById<tbl_Client>(23, c => c.cl_id);
mais je ne sais pas comment utiliser IDX et vérifier sa valeur contre l'id passé:
public T GetById<T>(int id, Expression<Func<T, object>> idx)
{
//var col = idx.Compile().Invoke(T);
// How do I check if the column passed to "idx" is equal to id?
return default(T);
}
EDIT: Pensez que cela fonctionne maintenant. Voici mon code entier, plus test:
public interface IDomainRepository
{
T GetById<T>(int id, Expression<Func<T, object>> idx) where T : class;
IEnumerable<T> GetAll<T>() where T : class;
IEnumerable<T> Query<T>(Expression<Func<T, bool>> filter) where T : class;
IEnumerable<T> Query<T>(ISpecification<T> filter) where T : class;
void Add<T>(T entity) where T : class;
void Delete<T>(T entity) where T : class;
Table<T> GetTable<T>() where T : class;
}
public class DomainRepository : IDomainRepository
{
private readonly DatabaseDataContext _ctx;
public DomainRepository(DatabaseDataContext ctx)
{
_ctx = ctx;
}
public T GetById<T>(int id, Expression<Func<T, object>> idx) where T : class
{
return (from i in GetAll<T>()
let h = idx.Compile().Invoke(i)
where Convert.ToInt32(h) == id
select i).SingleOrDefault();
}
public IEnumerable<T> GetAll<T>() where T : class
{
return GetTable<T>().ToList();
}
public IEnumerable<T> Query<T>(Expression<Func<T, bool>> filter) where T : class
{
return GetTable<T>().Where(filter);
}
public IEnumerable<T> Query<T> (ISpecification<T> filter) where T : class
{
return GetTable<T>().Where(filter.Predicate);
}
public void Add<T> (T entity) where T : class
{
GetTable<T>().InsertOnSubmit(entity);
}
public void Delete<T> (T entity) where T : class
{
GetTable<T>().DeleteOnSubmit(entity);
}
public Table<T> GetTable<T>() where T : class
{
return _ctx.GetTable(typeof(T)) as Table<T>;
}
}
var repository = new DomainRepository(_ctx);
var g = repository.GetById<tbl_Client>(1, c => c.cl_id);
Je vais continuer à tester ceci pour voir si c'est OK.
Cheers. Jas.
Vérifiez SQL généré par cette méthode. Autant que je sache, cela peut entraîner la matérialisation de toute la table et l'application de Linq aux objets. –