Próbowałem przekształcić wyrażenie LINQ w metodę i pracowałem zarówno nad wyjątkami "Internal .NET Framework Data Provider error 1025.
" i "".Nie można naprawić za pomocą LINQ do jednostek i LinqKit/PredicateBuilder
Oto odpowiednie części modelu jednostki (przy użyciu EF 4.2/LINQ do podmiotów):
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; }
}
Podstawowy model relacyjny jest taka:
Place (1) <-----> (0..*) PlaceName (0..*) <-----> (0..1) Language
Próbuję utworzyć zapytanie, które po uzyskaniu wyniku wyszukiwania term
, spróbuje znaleźć Place
podmiotów, których OfficialName
rozpoczyna się od OR, który ma PlaceName
, którego którego zaczyna się od wyszukiwania term
. (Language
nie jest, gdy mam problemy, choć jest częścią zapytania, ponieważ PlaceName
s powinien odpowiadać tylko za CultureInfo.CurrentUICulture.TwoLetterIsoLanguageName
.)
Poniższy kod działa:
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)
)
)
);
}
Co staram się zrobić dalej jest refactor NonOfficialNameMatches
metoda wyodrębnić wyrażenie name => ...
na osobną metodę, dzięki czemu może być ponownie wykorzystane przez inne zapytania. Oto jeden z przykładów próbowałem, który nie działa i zgłasza wyjątek „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)
)
);
}
Kiedy nie mam łańcuch .AsExpandable()
w NonOfficialNameMatches
, a następnie uzyskać»Internal .NET Framework Data Provider error 1025.
” wyjątek.
Śledziłem other advice here, takie jak kilka kombinacji wywoływania .Expand()
na predykatach, ale zawsze kończy się jednym z wyżej wymienionych wyjątków.
Czy można nawet wyodrębnić to wyrażenie w osobnej metodzie, używając LINQ do jednostek z LinqKit/PredicateBuilder? Jeśli tak, w jaki sposób? Co ja robię źle?
+100, dziękuję Zaczęłam myśleć, że to pytanie nie dostanie odpowiedzi. Dodatkowe wyjaśnienie też pomaga. – danludwig