Запутался в передаче аргументов Expression vs. Func

У меня проблемы с пониманием различий между работой Expressions и Funcs. Эта проблема возникла, когда кто-то изменил сигнатуру метода с:

public static List<Thing> ThingList(Func<Thing, bool> aWhere)

на

public static List<Thing> ThingList(Expression<Func<Thing, bool>> aWhere)

Что сломало мой код вызова. Старый код вызова (который работал) выглядел так:

        ...
        object y = new object();
        Func<Thing, bool> whereFunc = (p) => p == y;
        things = ThingManager.ThingList(whereFunc);

Новый код (который не работает) выглядит так:

        ...
        object x = new object();
        Expression<Func<Thing, bool>> whereExpr = (p) => p == x;
        things = ThingManager.ThingList(whereExpr);

Сбой внутри ThingList(...) на строке, использующей выражение:

        var query = (from t in context.Things.Where(aWhere)
        ...

С ошибкой времени выполнения:

Unable to create a constant value of type 'System.Object'. Only primitive types ('such as Int32, String, and Guid') are supported in this context.

Этот пример надуманный, но я предполагаю, что это как-то связано с тем, что локальная объектная переменная x не была правильно "скопирована" в выражение.

Может ли кто-нибудь объяснить, как справиться с этой ситуацией в целом, и почему Func работает, а Expression нет?

19
задан johnnyRose 27 October 2016 в 15:34
поделиться