Невозможно выполнить рефакторинг с использованием LINQ to Entities и LinqKit/PredicateBuilder

Я пытался реорганизовать выражение LINQ в метод и столкнулся с ошибкой 1025 внутреннего поставщика данных .NET Framework . . " и " Параметр 'xyz' не был связан в указанном выражении запроса LINQ to Entities. "исключения.

Вот соответствующие части модели объекта (с использованием EF 4.2 / LINQ to Entities):

public class Place : Entity
{
    public string OfficialName { get; protected internal set; }
    public virtual ICollection { 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; }
}

Базовая реляционная модель такова:

Place (1) <-----> (0..*) PlaceName (0..*) <-----> (0..1) Language

Я пытаюсь создать запрос, который при задании поискового термина попытается найти Placeобъектов, чье OfficialNameначинается с termИЛИ которые имеют PlaceName, чей Textили AsciiEquivalentначинается с поисковый запрос термин. ( Languageне вызывает у меня затруднений, хотя это часть запроса, потому что PlaceNameдолжны соответствовать только CultureInfo.CurrentUICulture.TwoLetterIsoLanguageName.)

Следующий код действительно работает:

internal static IQueryable WithName(this IQueryable queryable, 
    string term)
{
    var matchesName = OfficialNameMatches(term)
        .Or(NonOfficialNameMatches(term));
    return queryable.AsExpandable().Where(matchesName);
}

private static Expression> OfficialNameMatches(string term)
{
    return place => place.OfficialName.StartsWith(term);
}

private static Expression> 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)
            )
        )
    );
}

Далее я пытаюсь реорганизовать метод NonOfficialNameMatchesдля извлечения имени => .. .выражение в отдельный метод, чтобы его можно было повторно использовать в других запросах. Вот один пример, который я пробовал, который не работаети выдает исключение " Параметр "место" не был связан в указанном выражении запроса LINQ to Entities. ":

private static Expression> NonOfficialNameMatches(string term)
{
    return place => place.Names.AsQueryable().AsExpandable()
        .Any(PlaceNameMatches(term));
}

public static Expression> 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)
                )
            );
}

Когда у меня нет цепочки .AsExpandable()в NonOfficialNameMatches, я получаю исключение «Internal .NET Framework Data Provider error 1025. ». .

Я следовал другим советам здесь, таким как несколько комбинаций вызова .Expand()для предикатов, но всегда заканчивался одним из вышеупомянутых исключений.

Можно ли вообще выделить это выражение в отдельный метод, используя LINQ to Entities с LinqKit/PredicateBuilder?Если да, то как? Что я делаю не так?

6
задан Community 23 May 2017 в 10:09
поделиться