Ich habe versucht, einen LINQ-Ausdruck in eine Methode zu refactor, und habe in beiden "Internal .NET Framework Data Provider error 1025.
" und "The parameter 'xyz' was not bound in the specified LINQ to Entities query expression.
" Ausnahmen ausgeführt.Kann nicht mit LINQ to Entities und LinqKit/PredicateBuilder refactoring
Hier sind die relevanten Teile des Entity-Modell (mit EF 4.2/LINQ to Entities):
public class Place : Entity
{
public string OfficialName { get; protected internal set; }
public virtual ICollection<PlaceName> { get; protected internal set; }
}
public class PlaceName : Entity
{
public string Text { get; protected internal set; }
public string AsciiEquivalent { get; protected internal set; }
public virtual Language TranslationTo { get; protected internal set; }
}
public class Language : Entity
{
public string TwoLetterIsoCode { get; protected internal set; }
}
Das grundlegende relationale Modell ist dies:
Place (1) <-----> (0..*) PlaceName (0..*) <-----> (0..1) Language
Ich versuche, eine zu schaffen Abfrage, die, wenn eine Suche term
gegeben wird, versuchen, Place
Einheiten zu finden, deren OfficialName
beginnt mit der term
ODER wer hat eine PlaceName
wessen Text
oder AsciiEquivalent
beginnt mit der Suche term
. (Language
ist nicht, wo ich Probleme habe, obwohl es Teil der Abfrage ist, weil PlaceName
s nur für die CultureInfo.CurrentUICulture.TwoLetterIsoLanguageName
übereinstimmen sollte.)
Der folgende Code funktioniert:
internal static IQueryable<Place> WithName(this IQueryable<Place> queryable,
string term)
{
var matchesName = OfficialNameMatches(term)
.Or(NonOfficialNameMatches(term));
return queryable.AsExpandable().Where(matchesName);
}
private static Expression<Func<Place, bool>> OfficialNameMatches(string term)
{
return place => place.OfficialName.StartsWith(term);
}
private static Expression<Func<Place, bool>> NonOfficialNameMatches(string term)
{
var currentLanguage = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName;
return place => place.Names.Any(
name =>
name.TranslationToLanguage != null
&&
name.TranslationToLanguage.TwoLetterIsoCode == currentLanguage
&&
(
name.Text.StartsWith(term)
||
(
name.AsciiEquivalent != null
&&
name.AsciiEquivalent.StartsWith(term)
)
)
);
}
Was ich als nächstes versuchen will, ist die NonOfficialNameMatches
Methode umzuformen, um den name => ...
Ausdruck in eine separate Methode zu extrahieren, so dass sie von anderen Abfragen wiederverwendet werden kann. Hier ist ein Beispiel, das ich versucht habe, die nicht funktioniert und wirft die Ausnahme „The parameter 'place' was not bound in the specified LINQ to Entities query expression.
‚:
private static Expression<Func<Place, bool>> NonOfficialNameMatches(string term)
{
return place => place.Names.AsQueryable().AsExpandable()
.Any(PlaceNameMatches(term));
}
public static Expression<Func<PlaceName, bool>> PlaceNameMatches(string term)
{
var currentLanguage = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName;
return name =>
name.TranslationToLanguage != null
&&
name.TranslationToLanguage.TwoLetterIsoCode == currentLanguage
&&
(
name.Text.StartsWith(term)
||
(
name.AsciiEquivalent != null
&&
name.AsciiEquivalent.StartsWith(term)
)
);
}
Wenn ich nicht die .AsExpandable()
Kette in NonOfficialNameMatches
haben, dann erhalte ich die‘Internal .NET Framework Data Provider error 1025.
“ Ausnahme.
Ich habe other advice here wie mehrere Kombinationen von Aufruf .Expand()
auf die Prädikate gefolgt, aber immer mit einer der oben genannten Ausnahmen enden.
Ist es sogar möglich, diesen Ausdruck in eine separate Methode auszufiltern, die LINQ zu Entities mit LinqKit/PredicateBuilder verwendet? Wenn ja, wie? Was mache ich falsch?
+100, danke ich begann diese Frage zu denken, würde nie beantwortet werden. Die zusätzliche Erklärung hilft auch. – danludwig