Entity Framework und Repository-Muster (problem mit IQueryable)
Ich wechselte von Linq 2 SQL Entity Framework, und ich sehe einige merkwürdige Verhaltensweisen, die im EF, dass ich bin der Hoffnung, jemand kann helfen, mit. Ich habe versucht zu Googeln um, aber ich war nicht in der Lage zu finden, anderen Menschen mit diesem problem. Ich habe verspottet, bis ein Szenario zu erklären, die situation.
Wenn ich arbeite direkt mit einem EF-context -, ich bin in der Lage, ein select in einem select. Zum Beispiel, diese führt völlig in Ordnung:
//this is an Entity Framework context that inherits from ObjectContext
var dc = new MyContext();
var companies1 = (from c in dc.Companies
select new {
Company = c,
UserCount = (from u in dc.CompanyUsers
where u.CompanyId == c.Id
select u).Count()
}).ToList();
Allerdings, wenn ich ein repository-Muster, bei dem das repository zurück IQueryable (oder sogar ObjectSet oder ObjectQuery), bekomme ich eine NotSupportedException (LINQ to Entities nicht erkennt die Methode 'System.Linq -.IQueryable`1)...
Hier ist ein Beispiel meiner repository:
public class Repository {
private MyContext _dc;
public Repository() {
_dc = new MyContext();
}
public IQueryable<Company> GetCompanies() {
return _dc.Companies;
}
public IQueryable<CompanyUser> GetCompanyUsers() {
return _dc.CompanyUsers;
}
}
//Ich bin mit dem repository in eine andere Klasse (z.B. in meiner Dienstschicht)
var repository = new Repository();
var companies2 = (from c in repository.GetCompanies()
select new {
Company = c,
UserCount = (from u in repository.GetCompanyUsers()
where u.CompanyId == c.Id
select u).Count()
}).ToList();
Der obige code löst eine NotSupportedException.
Merke ich, dass wenn es einen Zusammenhang zwischen den Unternehmen und CompanyUsers, dann kann ich einfach tun und es wird funktionieren:
var companies3 = (from c in repository.GetCompanies()
select new {
Company = c,
UserCount = (from u in c.CompanyUsers
select u).Count()
}).ToList();
...aber mein Beispiel ist nur eine vereinfachte version der ein komplizierteres Szenario, wo ich nicht haben eine Assoziation zwischen den Entitäten.
So, ich bin sehr verwirrt, warum Entity Framework wirft die NotSupportedException aus. Wie kommt es, dass die Abfrage funktioniert, völlig in Ordnung, wenn ich arbeiten bin mit dem EF-context direkt, aber es ist nicht unterstützt, wenn ich arbeiten bin mit IQueryable zurückgegeben, die von einer anderen Methode. Dies funktionierte einwandfrei mit Linq 2 SQL, aber es scheint nicht zu funktionieren in Entity Framework.
Jede Einsicht würde sehr geschätzt werden.
Vielen Dank im Voraus.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich vermute, dass das, was passiert ist, dass EF sieht der Ausdruck für
repository.GetCompanyUsers()
innerhalb der lambda-Ausdruck für die ersteselect
und nicht weiß, was zu tun, weilrepository
ist nicht ein EF-context. Ich denke, dass, wenn Sie pass in die IQueryable direkt, anstatt eines Ausdrucks, die gibt es, es sollte funktionieren.Wie wäre es, wenn Sie dies tun:
Dies ist einer jener seltsamen Macken mit Linq to SQL/EF. Offenbar setzten Sie eine Möglichkeit, zu übersetzen, von einem getter Eigenschaft zu SQL, aber nicht in einer Weise zu übersetzen, aus einer getter - Funktion zu SQL.
Wenn anstelle der Funktion
GetCompanyUsers()
verwenden Sie eine Eigenschaft wieCompanyUsers
sollte es funktionieren.Komisch gell?
Also statt
Sie tun könnten,
Soweit parametrisierte Abfragen gehen (was Sie nicht tun können, mit einer Immobilie, natürlich), siehe meine Frage hier beantwortet: Benutzerdefinierte Funktion in Entity Framework query manchmal übersetzt richtig, manchmal nicht
Können Sie auch
wheres
undselects
in der Eigenschaft zu; Sie werden übersetzen in Ordnung. Zum Beispiel, wenn ich einen blog mit einer Artikel-Tabelle, die enthält einige Artikel, die nicht online:Werde, dass auch eine Verringerung der Anzahl von parametrisierten Abfragen, die Sie benötigen.