Проблема Linq To SQL - не поддерживает перевод на SQL (проблема с свойством С#)

Я расширяю некоторые классы Linq to SQL. У меня есть 2 похожих оператора, первый работает, второй не имеет (ошибка "не поддерживается поддержкой SQL" ).

var reg2 = rs.ProductRegistrations().SingleOrDefault(p => p.Product.product_name == "ACE")

var reg5 = rs.ProductRegistrations().SingleOrDefault(p => p.product_name == "ACE");

Прочитав эту ссылку LINQ: Нет перевода на SQL

Я понимаю (я думаю), что в принципе все должно быть "inline", иначе дерево выражений невозможно вычислить правильно. Первый пример напрямую обращается к LinqToSql EntitySet "Продукт" (сохраняя все в строке), тогда как второй пример использует свойство, которое определяется следующим образом:

public partial class ProductRegistration :IProduct
{
    public string product_name
    {
        get { return this.Product.product_name; }
    }
}

Я предполагаю, что моя проблема в том, что LinqToSql не может перевести это.

Как мне превратить "свойство" в эквивалентную инструкцию? Я знаю, что мне нужно использовать выражение System.Linq.Expressions.Expression, но все, что я пробовал, не работает (некоторые даже не компилируются). Может быть, мне нужно сделать метод расширения (используя выражение), а затем вызвать это из свойства? Может ли свойство вызвать метод расширения?

Такие вещи, как ниже, не работают:

public static System.Linq.Expressions.Expression<Func<IProduct, bool>> ProductName2 (string pname)
{
    return (p => p.product_name == pname);
}

В нижней строке, я знаю, что мне нужно обернуть мой метод доступа в "Expression <.... > ", но я не знаю, как получить доступ к этому из свойства, так что переменная "reg5" выше будет работать правильно.

Было бы здорово, если бы был какой-то волшебный атрибут, который я мог бы просто добавить к свойству в свойство "авто-выражение" и сделать LinqToSql счастливым, вместо того, чтобы обернуть его в Expression <... >

Хотелось бы это сделать...

public partial class ProductRegistration :IProduct
{
    [Auto-Expression]
    public string product_name
    {
        get { return this.Product.product_name; }
    }
}

ИЗМЕНИТЬ Ниже приведена ссылка и ответ ниже. Удивительно, спасибо. Вторая часть моего вопроса, опять же у меня есть 2 похожих утверждения, первый работает, второй не имеет (ошибка "не поддерживается поддержкой SQL" ).

var reg = rs.ProductRegistrations().ProductName("ACE").WithTranslations().SingleOrDefault();

var reg2 = rs.ProductRegistrations2().ProductName("ACE").WithTranslations().SingleOrDefault();

Разница в них заключается в том, что первый возвращает IQueryable конкретного класса "IQueryable [ProductRegistration]", тогда как второй возвращает IQueryable интерфейса "IQueryable [IProduct]". Я бы хотел использовать второй, потому что я могу пощекотать интерфейс по многим различным классам, и он более общий, но, похоже, он не работает. Любые идеи?

Ответы

Ответ 1

Было бы здорово, если бы был какой-то волшебный атрибут, который я мог бы просто добавить к свойству в свойство "авто-выражение" и сделать LinqToSql счастливым, вместо того, чтобы обернуть его в Expression <... >

Есть, почти. Вам все равно придется выполнять какую-то работу, но Damien Guard и друзья сделали для вас тяжелую роль: Свойства клиентской стороны и любой удаленный поставщик LINQ

Замечательно, что он работает с любым поставщиком LINQ, который поддерживает используемые вами выражения.

Обновление: Проблема с вашей второй версией (с интерфейсом) заключается в том, что поставщик Queryable должен будет выяснить, что представляет собой интерфейс-интерфейс, поскольку он должен транслитерировать этот в имя таблицы. Но весь смысл интерфейса заключается в том, что пользователь интерфейса должен быть агностическим в отношении типа реализации, поэтому поставщик будет работать в разных целях с интерфейсом. Поэтому я не думаю, что вторая форма будет работать.