Создайте метод, который будет возвращать лямбда-выражение, которое будет использоваться в выражении лямбда-выражения WHERE.Получил ошибку 1025 - PullRequest
2 голосов
/ 19 октября 2010

Я использую Framework Entity 4 в своем проекте.Я хотел бы создать функцию, которая будет возвращать выражение Ничего не работает.Я получаю эту Внутреннюю .Net Framework Data Provider error 1025.

Вот мой метод выражения

   public Expression<Func<SupplierTypeText, bool>> GetLmbLang()
   {
       return (p => p.LangID == 1);
   }

Я вызываю метод GetLmbLang и получаю ошибку.

<code>var ViewModel = _db.Suppliers.Select(model => new {
                model,
                SupType = model.SupplierType.SupplierTypeTexts.Where(repBase.GetLmbLang().Compile())
            });

            Response.Write("<pre>");
            Response.Write(((ObjectQuery)ViewModel).ToTraceString());
            Response.Write("
");

Если янаписать выражение непосредственно в предложении WHERE, проблем нет.

var ViewModel = _db.Suppliers.Select(model => new {
                model,
                SupType = model.SupplierType.SupplierTypeTexts.Where(p => p.LangID == 1)
            });

Спасибо.

1 Ответ

2 голосов
/ 19 октября 2010

Это потому, что вы вызываете Метод компиляции в своем выражении, и вам это не нужно.Вы должны просто передать repBase.GetLmbLang() в качестве предиката для метода Where следующим образом:

SupType = model.SupplierType.SupplierTypeTexts.Where(repBase.GetLmbLang())


EDIT:
Я думаю, вы немного не поняли, когдаВы должны использовать Expression<Func<SupplierTypeText, bool>>, а когда только Func<SupplierTypeText, bool>.

В основном, когда вы вызываете Где метод на model.SupplierType.SupplierTypeTexts, который вы вызываете Enumerable.Where Метод с этой подписью (LINQ to Objects):

public static IEnumerable<TSource> Where<TSource>(
        this IEnumerable<TSource> source,
        Func<TSource, bool> predicate
)

Но, предоставив Expression<Func<SupplierTypeText, bool>>, вы действительно имели в виду Queryable.Where , который имеет эту подпись (LINQ to Entities):

public static IQueryable<TSource> Where(
        this IQueryable<TSource> source,
        Expression<Func<TSource, bool>> predicate
)

Теперь произошло то, что при кодировании model.SupplierType.SupplierTypeTexts.Where(repBase.GetLmbLang()) SupplierTypeTexts заполняется из базы данных ленивой загрузкой и становится готовым EntityCollection в памяти для запроса, поэтому ваше первое решение состоит в том, чтобы соответственно изменить метод GetLmbLang () :

public Func<SupplierTypeText, bool> GetLmbLang() {
       return (p => p.LangID == 1);
}

и затем вызвать его так в анонимном классе:

SupType = model.SupplierType.SupplierTypeTexts.Where(repBase.GetLmbLang())

Ваша секундаРешение было бы сохранить метод GetLmbLang () в том виде, в каком он есть сейчас, и фактически изменить способ создания SupType :

var ViewModel = _db.Suppliers.Select(model => new {
                model,
                SupType = _db.SupplierTypeTexts
                             .Where(repBase.GetLmbLang())
            });


Примечание об ошибке провайдера 1205 :
Это исключение происходит только тогда, когда вымы делаем проекцию с анонимными типами и передаем Expression<Func<...>> внутри, как показано ниже:

var ViewModel = _db.Suppliers.Select(model => new {
        SupType = _db.SupplierTypeTexts.Where(repBase.GetLmbLang())
});

Если вы удаляете проекцию с анонимным типом или сохраняете проекцию и избавляетесь от метода, который возвращаетExpression<Func<...>> оно уйдет.Почему это происходит?Понятия не имею, для меня это звучит как ошибка провайдера.Но одна вещь наверняка состоит в том, что теоретически это должно работать, и в этом коде нет абсолютно ничего плохого.При этом, не стесняйтесь, чтобы начать новый вопрос и посмотреть, что другие парни должны сказать.
Если вы хотите это сделать, тогда заголовок вашего вопроса должен выглядеть примерно так: Why am I getting Provider Error 1205 exception when I try to do a projection with anonymous type while passing in an Expression<Func<...>>?

...