2011-07-22 8 views
5

Ecco la cosa.Come portare il metodo di estensione Entity Framework Include a un IQueryable generico <TSource>

ho un'interfaccia, e vorrei mettere il metodo Include estensione, che appartiene a EntityFramework biblioteca, alla mia IRepository strato wich Non ha bisogno di sa di EntityFramework.

public interface IRepository<TEntity> 
{ 
    IQueryable<TEntity> Entities { get; } 

    TEntity GetById(long id); 
    TEntity Insert(TEntity entity); 
    void Update(TEntity entity); 
    void Delete(TEntity entity); 
    void Delete(long id); 
} 

così ho il metodo di estensione:

public static class IncludeExtension 
{ 
    static IQueryable<TEntity> Include<TEntity>(this IQueryable<TEntity> query, 
     string path) 
    { 
     throw new NotImplementedException(); 
    } 
} 

Ma non so come implementarlo in questo strato, e vorrei inviare al mio EntityFramework (o qualsiasi altra cosa che implementerà l'IRepository) da trattare.

Mi serve lo stesso per un'interfaccia con un metodo di estensione.

Qualsiasi luce?

risposta

2

questa domanda è un po 'vecchio, ma qui ci sono due soluzioni EF-indipendente se voi o qualcun altro è ancora alla ricerca: a base di riflessione

1. Soluzione

Questa soluzione è ciò che il. NET Framework ricade su se il IQueryable non esegue il cast su DbQuery o ObjectQuery. Salta questi calchi (e l'efficienza che fornisce) e hai disaccoppiato la soluzione da Entity Framework.

public static class IncludeExtension 
{ 
    private static T QueryInclude<T>(T query, string path) 
    { 
     MethodInfo includeMethod = query.GetType().GetMethod("Include", new Type[] { typeof(string) }); 

     if ((includeMethod != null) && typeof(T).IsAssignableFrom(includeMethod.ReturnType)) 
     { 
      return (T)includeMethod.Invoke(query, new object[] { path }); 
     } 

     return query; 
    } 

    public static IQueryable<T> Include<T>(this IQueryable<T> query, string path) where T : class 
    { 
     return QueryInclude(query, path); 
    } 

    // Add other Include overloads. 
} 

2. Dyanmics basato su soluzioni

Qui il metodo QueryInclude<T> utilizza il tipo dynamic per evitare riflessione.

public static class IncludeExtension 
{ 
    private static T QueryInclude<T>(T query, string path) 
    { 
     dynamic querytWithIncludeMethod = query as dynamic; 

     try 
     { 
      return (T)querytWithIncludeMethod.Include(path); 
     } 
     catch (RuntimeBinderException) 
     { 
      return query; 
     } 
    } 

    public static IQueryable<T> Include<T>(this IQueryable<T> query, string path) where T : class 
    { 
     return QueryInclude(query, path); 
    } 

    // Add other Include overloads. 
} 
3

Include è un'astrazione che perde e funziona solo con Entity framework. EF 4.1 already contains su generico IQueryable ma internamente converte solo passato generico IQueryable in generico ObjectQuery o DbQuery e chiama il proprio Include.

Ecco alcuni esempi su come eseguire il wrapping di tale include in repository (l'implementazione del repository dipende da EF in modo che possa utilizzare direttamente Include fornita da EF).

+0

Quindi, io non voglio depeding su EF. Sto cercando di evitare riferimenti nel mio livello client. – iuristona

0

In Entity Framework 5.0 ora forniscono un metodo di estensione a IQueryable per aggiungere la funzionalità Includi. Sarà sufficiente aggiungere un "System.Data.Entity" usando per risolvere il metodo di estensione. Per la documentazione diretta vai here

Problemi correlati