I am trying to reorganize the LINQ expression into a method and have thrown the exceptions " Internal .NET Framework Data Provider error 1025.
" and " The parameter 'xyz' was not bound in the specified LINQ to Entities query expression.
".
Here are the relevant parts of the entity model (using 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; } }
The basic relational model is as follows:
Place (1) <-----> (0..*) PlaceName (0..*) <-----> (0..1) Language
I'm trying to create a query that, when searching for term
will try to find the Place
entity whose OfficialName
starts with term
OR, which has a PlaceName
, whose Text
or AsciiEquivalent
starts with a search for term
. ( Language
not where I am having problems, although this is part of the request, because PlaceName
should only match CultureInfo.CurrentUICulture.TwoLetterIsoLanguageName
.)
The following code works :
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) ) ) ); }
What I'm trying to do next is reorganizing the NonOfficialNameMatches
method to extract the name => ...
expression into a separate method so that it can be reused by other queries. Here is one example I tried that does not work and throws an exception " 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) ) ); }
When I don't have the .AsExpandable()
chain in NonOfficialNameMatches
, then I get the exception " Internal .NET Framework Data Provider error 1025.
".
I followed other advice here , for example with several combinations of calling .Expand()
on predicates, but always ends with one of the above exceptions.
Is it even possible to split this expression into a separate method using LINQ to Entities with LinqKit / PredicateBuilder? If so, how? What am I doing wrong?