2011-01-04 19 views
1

Ich versuche, einige Geschäftslogik auf EntityFramework v4 zu haken, und der beste Ort, den ich tun kann, ist, bevor eine Abfrage ausgeführt wird.IQueryProvider überschreiben

Ich hatte gehofft, ich würde die Standard IQueryProvider, einfaches Hinzufügen eines Verfahrens Haken in Execute (Expression ausdr) außer Kraft setzen können:

public TResult Execute<TResult>(Expression expression) 
    { 
     // Do stuff here. 
     return this.BaseProvider.Execute<TResult>(expression); 
    } 

Allerdings bin ich Schwierigkeiten haben, die IQueryable immer meine IQueryProvider verwenden (Das ObjectQuery-Objekt hat ein Attribut Provider {}, aber es wird nur get und gibt eine vordefinierte Klasseninstanz zurück). Gibt es eine Möglichkeit, Ihren eigenen benutzerdefinierten IQueryProvider auf diese Weise zu verwenden, ohne einen vollständigen neuen Abfrage-Stack (ObjectSet, ObjectContext usw.) zu schreiben?

EDIT

Leider: Ich spreche keine neuen Klassen, wenn möglich, mit Ausnahme des einen über das Hinzufügen, die IQueryProvider implementiert. Ein Wrapper ist grundsätzlich in Ordnung, aber da ich nicht die Absicht, die Umsetzung IObjectSet oder Subklassen Object <T> den Wrapper habe nur auf dem ersten Durchgang durch Create verwendet werden:

public IQueryable<TElement> CreateQuery<TElement>(Expression expression) 
    { 
     return this.BaseProvider.CreateQuery<TElement>(expression); 
    } 

Nach diesem Punkt, wie ich bin mit dem Standard-ObjectSet innerhalb des Wrappers wird der IQueryProvider auf den vordefinierten zurückgesetzt und mein IQueryProvider wird keine weiteren Aufrufe abfangen.

Also: Gibt es eine Möglichkeit zur Implementierung und Verwendung von IQueryProvider, OHNE dass versucht wird, einen Wrapper hinzuzufügen, der mich dazu zwingt, einen vollständigen benutzerdefinierten Stapel von IQueryxxx-Objekten zu verwenden?

Antwort

1

Ja gerade in den abfragbaren Anbieter in der Create Haken und Methoden Execute

public object Execute(Expression expression) 
{ 
//do stuff here 
return _queryable.Provider.Execute(expression); 
} 

Sie müssen nur wie so die abfragbaren Objekt injizieren

public class MyQueryable<T> : IOrderedQueryable<T> 
{ 
public MyQueryable(IQueryable<T> toWrap) 
    : this(equipment, Expression.Constant(equipment.AsQueryable())) 
{ 
} 

public MyQueryable(IQueryable<T> toWrap, Expression expression) 
{ 
    Wrapped = toWrap; 
    Provider = new MyProvider<T>(toWrap); 
    Expression = expression; 
} 

public IEnumerator<TModel> GetEnumerator() 
{ 
    return Wrapped.GetEnumerator(); 
} 

IEnumerator IEnumerable.GetEnumerator() 
{ 
    return GetEnumerator(); 
} 

public Expression Expression { get; private set; } 

public Type ElementType 
{ 
    get { return typeof(T); } 
} 

public IQueryProvider Provider { get; private set; } 
internal IQueryable<T> Wrapped { get; set; } 
}