2008-09-17 13 views
6

Inspiriert von der MVC-Storefront verwendet das letzte Projekt, an dem ich gerade arbeite, Erweiterungsmethoden für IQueryable, um Ergebnisse zu filtern.Erweiterungsmethoden funktioniert nicht für eine Schnittstelle

Ich habe diese Schnittstelle;

IPrimaryKey 
{ 
    int ID { get; } 
} 

und ich habe diese Erweiterung Methode

public static IPrimaryKey GetByID(this IQueryable<IPrimaryKey> source, int id) 
{ 
    return source(obj => obj.ID == id); 
} 

Sagen wir, ich habe eine Klasse, SimpleObj die IPrimaryKey implementiert. Wenn ich ein IQueryable von SimpleObj habe, existiert die GetByID-Methode nicht, es sei denn, ich habe explizit als IQueryable von IPrimaryKey gecastet, was weniger als ideal ist.

Fehle ich hier etwas?

Antwort

13

Es funktioniert wenn es richtig gemacht wird. Die Lösung von cfeduke funktioniert. Allerdings müssen Sie nicht die IPrimaryKey Schnittstelle generic, in der Tat zu machen, müssen Sie nicht auf Ihre ursprüngliche Definition ändern:

public static IPrimaryKey GetByID<T>(this IQueryable<T> source, int id) where T : IPrimaryKey 
{ 
    return source(obj => obj.ID == id); 
} 
+0

Excellent - ich die ursprüngliche Antwort nicht akzeptiert haben. Ich werde das morgen versuchen. Danke euch beiden. – Kirschstein

+1

Ich möchte nur sagen, dass meine Antwort nicht falsch war, es war der Grund, warum sein Code nicht funktionierte, ich nahm mir einfach nicht die Zeit, eine Lösung auszuarbeiten. Up wählte deine bessere Antwort. –

+0

Nur ein sehr kleiner Punkt: IPrimaryKey // bessere Integration: Es sollte (diese IQueryable Quelle ... – Kirschstein

2

Dies kann nicht funktionieren, da Generika Vererbungsmuster nicht folgen können. dh. IQueryable <SimpleObj> ist nicht in dem Vererbungsbaum von IQueryable <IPrimaryKey>

4

Edit: Konrad ‚s Lösung ist besser, weil sein viel einfacher. Die folgende Lösung funktioniert, ist aber nur in Situationen erforderlich, die der ObjectDataSource ähnlich sind, wobei eine Methode einer Klasse durch Reflektion abgerufen wird, ohne die Vererbungshierarchie zu durchlaufen. Offensichtlich passiert das hier nicht.

Dies ist möglich, ich habe ein ähnliches Muster zu implementieren, als ich mit Object eine benutzerdefinierte Entity Framework-Lösung für die Bearbeitung von:

public interface IPrimaryKey<T> where T : IPrimaryKey<T> 
{ 
    int Id { get; } 
} 

public static class IPrimaryKeyTExtension 
{ 
    public static IPrimaryKey<T> GetById<T>(this IQueryable<T> source, int id) where T : IPrimaryKey<T> 
    { 
     return source.Where(pk => pk.Id == id).SingleOrDefault(); 
    } 
} 

public class Person : IPrimaryKey<Person> 
{ 
    public int Id { get; set; } 
} 

Snippet Verwendung:

var people = new List<Person> 
{ 
    new Person { Id = 1 }, 
    new Person { Id = 2 }, 
    new Person { Id = 3 } 
}; 

var personOne = people.AsQueryable().GetById(1); 
Verwandte Themen