2010-02-11 2 views
16

Ich habe eine Klasse Post, die ein Entity Framework Modell ist. Es enthält eine Eigenschaft wie folgt:Wie verwendet man eine benutzerdefinierte Eigenschaft in einer LINQ-to-Entities-Abfrage?

public bool Showable { 
    get { 
    return this.Public && this.PublishedDate > DateTime.now 
    } 
} 

ich es in einer Abfrage wie folgt verwendet werden:

from p in db.Posts where p.Showable select p; 

aber wenn ich eine Eigenschaft, die es verwendet, wie diese

public IEnumerable<Post> ShowablePosts { 
    get { 
    return from p in db.Posts where p.Showable select p; 
    } 
} 

dann kann ich nicht:

from p in ShowablePosts where p.Id > 42 select p; 

Es ist ays:

Der angegebene Typ member 'Showable' wird in LINQ to Entities nicht unterstützt. Es werden nur Initialisierungs-, Entitäts- und Entitätsnavigationseigenschaften unterstützt.

Antwort

1

Leider ist das Entity Framework einfach nicht berechneten Eigenschaften nicht unterstützt (das heißt, eine Eigenschaft, die einen berechneten Wert zurückgibt, anstatt einen Verweis auf ein Trägerfeld), aber it may be supported at a future date.

+0

Ich kann berechnete Eigenschaften in einer Abfrage in Ordnung, aber nicht in einer Methode, die eine Abfrage ausführt. Es ist komisch. – Pablo

+0

Ich lebe in der Linq-to-SQL-Welt im Moment, ist 'Rückkehr von p in db.Posts wo p.Showable wählen p;' nativ ein 'IQueryable ' oder 'IEnuemerable ' in EF? Und würde das auf seine Frage einwirken? –

+0

@J. Pablo Fernandez: Linq-Abfrage wird nicht ausgeführt, wenn Sie sie definieren, nur wenn Sie etwas tun, das die tatsächlichen Ergebnisse benötigt. Es gibt viele Dinge, die Linq unterstützt, aber das Entity Framework nicht, und diese Dinge werden erst bei der Ausführung der Abfrage offensichtlich. –

19

Sie können dies tun, wenn Sie schreiben die Eigenschaft als Expression, die in SQL übersetzt werden kann.

Here's how to do it.

Das ist ein bisschen kompliziert ist, weil es sich um eine allgemeine Lösung für ein kompliziertes Problem.

Die allgemeine Idee ist dies: LINQ zu Entities (wie alle LINQ-Anbieter) können kompilierten Code wie Ihre Eigenschaft zur Laufzeit nicht in SQL übersetzen. LINQ to Objects kann kompilierten Code ausführen, aber es kann nicht übersetzen es. Aber sie können übersetzen Expression<T>. So könnte man schreiben:

public static Expression<Func<Post, bool>> WhereActive 
{ 
    get 
    { 
     return p => p.Public && p.PublishedDate > DateTime.Now; 
    } 
} 

Dann könnten Sie schreiben:

public IEnumerable<Post> ShowablePosts 
{ 
    get 
    { 
     return db.Posts.Where(WhereActive); 
    } 
} 

... und LINQ to Entities, dass übersetzen könnte. Der Code im Post-I-Link verallgemeinert diese Idee.

+0

Gibt es eine Möglichkeit, einen Parameter an WhereActive zu übergeben? Zum Beispiel die DateTime. Wenn dies der Fall ist, können Sie möglicherweise https: // stackoverflow beantworten.com/q/48497487/2968001 –

0

Ich denke, der einfachste Weg, dies zu tun ist mit Computed Attribut DelegateDecompiler.EntityFramework Paket, das in this answer erwähnt.

Verwandte Themen