2017-11-24 3 views
1

Ich habe eine User Klasse mit der Navigationseigenschaft Settings und eine schreibgeschützte Eigenschaft IsVisibleInApp.Entity Framework Core LINQ-Klasseneigenschaft/Methoden können keine eingeschlossene Eigenschaft verwenden

Derzeit ist dieser Code funktioniert:

var users = context.Users.Include(x => x.Settings) 
    .Where(x => x.Settings.IsApproved && x.Settings.IsAvailable && x.UserType == 2); 

Aber ich habe diese Kontrollen häufig verwenden, so dass ich versuchen, eine Eigenschaft zu verwenden, und es wird Settings als null zur Laufzeit.

Hier ist mein Code.

public bool IsVisibleInApp 
{ 
    get 
    { 
    return this.Settings.IsApproved && this.Settings.IsAvailable && this.UserType == 2; 
    } 
} 

... 
... 

void SomeMethod(){ 
    var users = context.Users.Include(x => x.Settings) 
     .Where(x => x.IsVisibleInApp).ToList(); 

kann ich sehen, dass der Fremdschlüssel this.SettingsID ein gültiger Wert ist. Ich denke, Eigenschaften/Methoden können in Where Klauseln auf DBSets nicht verwendet werden, wie sie in SQL konvertiert werden? Aber sicher gibt es einen Weg um dies ... Oder muss ich zuerst eine .ToList() machen und dann einen weiteren .Where Aufruf verwenden, aber das würde bedeuten, alle Zeilen aus der Datenbank zu ziehen, was wie eine Menge zusätzlicher Arbeit erscheint. .

+0

Ich glaube, Sie Ihre eigene Frage beantwortet. Warum würde Ihre Datenbank Ihren C# -Code unterlaufen, oder warum würde LINQ versuchen, jeden zufälligen C# -Code, den Sie darauf werfen, in SQL zu übersetzen? Es kann das ursprüngliche Lambda übersetzen, aber nicht getter der Eigenschaft. Wenn das funktionieren würde, schließen Sie als nächstes einen Service-Aufruf oder I/O zu einer anderen Datenbank in diesem Getter ein und erwarten immer noch, dass das Ganze auf Ihrem DB-Server ausgeführt wird? – oerkelens

Antwort

1

Sie können es die Art und Weise nicht tun Sie wollen (EF in Ihrem Eigentum Getter und schauen gehen nicht, was Sie da tun), aber Sie können das in statischer Ausdruck Einwickeln Code Wiederholung reduzieren:

public static Expression<Func<User, bool>> IsVisibleInAppExpression = x => 
    x.Settings.IsApproved && x.Settings.IsAvailable && x.UserType == 2; 

Und dann wie folgt verwenden:

var users = context.Users.Include(x => x.Settings) 
    .Where(User.IsVisibleInAppExpression).ToList(); 

oder durch die Schaffung von Erweiterungsmethode:

public static class Extensions { 
    public static IQueryable<User> VisibleInAppOnly(this IQueryable<User> query) 
    { 
     return query.Where(x => 
      x.Settings.IsApproved && x.Settings.IsAvailable && x.UserType == 2); 
    } 
} 

Und mit wie folgt aus:

var users = context.Users.Include(x => x.Settings).VisibleInAppOnly(); 
Verwandte Themen