7 votes

Essayer d'utiliser un générique avec Entity Framework

Tout d'abord, je ne suis pas sûr que cela soit possible. Je suis en train d'apprendre les génériques et j'ai plusieurs dépôts dans mon application. J'essaie de créer une interface qui prend un type générique et le convertit en quelque chose dont tous les référentiels peuvent hériter. J'en viens maintenant à ma question.

public interface IRepository<T>
{
    IEnumerable<T> FindAll();
    IEnumerable<T> FindById(int id);
    IEnumerable<T> FindBy<A>(A type);
}

Est-il possible d'utiliser un générique pour déterminer ce qu'il faut trouver par ?

public IEnumerable<SomeClass> FindBy<A>(A type)
{
    return _context.Set<SomeClass>().Where(x => x. == type); // I was hoping to do x.type and it would use the same variable to search.
}

Pour clarifier un peu plus, je considérais qu'il s'agissait d'une chaîne, d'un int ou de n'importe quel autre type que je souhaitais rechercher. Ce que j'espère, c'est que je puisse dire x.quelque chose où quelque chose est égal à la variable passée.

Je peux définir n'importe quel référentiel comme contexte de base de données en utilisant l'option

public IDbSet<TEntity> Set<TEntity>() where TEntity : class
{
    return base.Set<TEntity>();
}

Des suggestions ?

4voto

Trevor Pilley Points 7304

Si vous utilisez Expression<Func<T, bool>> au lieu de A comme ceci :

public interface IRepository<T>
{
    ... // other methods
    IEnumerable<T> FindBy(Expression<Func<T, bool>> predicate);
}

Vous pouvez interroger le type à l'aide de linq et spécifier la requête dans le code qui appelle la classe de référentiel.

public IEnumerable<SomeClass> FindBy(Expression<Func<SomeClass, bool>> predicate)
{
    return _context.Set<SomeClass>().Where(predicate);
}

Et appelez-le ainsi :

var results = repository.FindBy(x => x.Name == "Foo");

Et comme il s'agit d'une expression générique, il n'est pas nécessaire de l'implémenter dans chaque référentiel, vous pouvez l'avoir dans le référentiel de base générique.

public IEnumerable<T> FindBy(Expression<Func<T, bool>> predicate)
{
    return _context.Set<T>().Where(predicate);
}

0voto

phil soady Points 4463

J'utilise une combinaison d'interfaces et de classes abstraites pour atteindre cet objectif.

public class RepositoryEntityBase<T> : IRepositoryEntityBase<T>, IRepositoryEF<T> where T : BaseObject
 // 
public RepositoryEntityBase(DbContext context)
    {
        Context = context;
//etc

public interface IRepositoryEntityBase<T> : IRepositoryEvent where T : BaseObject //must be a model class we are exposing in a repository object

{
    OperationStatus Add(T entity);
    OperationStatus Remove(T entity);
    OperationStatus Change(T entity);
   //etc

Les classes dérivées peuvent alors avoir quelques méthodes spécifiques à l'objet, voire rien du tout, et se contenter de fonctionner.

public class RepositoryModule : RepositoryEntityBase<Module>, IRepositoryModule{
    public RepositoryModule(DbContext context) : base(context, currentState) {}
}
//etc

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X