Я расширяю некоторые классы Linq для 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
Я понимаю (я думаю), что в основном все должно быть "встроенным", иначе дерево выражений не может быть правильно рассчитано. Первый пример напрямую обращается к LinqToSql EntitySet «Product» (сохраняя все в строке), тогда как во втором примере используется свойство, которое определяется следующим образом:
public partial class ProductRegistration :IProduct
{
public string product_name
{
get { return this.Product.product_name; }
}
}
Я предполагаю, что моя проблема в том, что LinqToSql не может перевести это.
Как бы я превратил "свойство" в эквивалентное утверждение? Я знаю, что должен использовать System.Linq.Expressions.Expression, но все, что я пробовал, не работает (некоторые даже не компилируются). Может быть, мне следует создать метод Extension (используя Expression), а затем вызвать его из свойства? Может ли свойство вызвать метод расширения ??
Такие вещи, как показано ниже, не работают:
public static System.Linq.Expressions.Expression<Func<IProduct, bool>> ProductName2 (string pname)
{
return (p => p.product_name == pname);
}
Итог, я знаю, что мне нужно обернуть мой метод доступа в "выражение <....>", но я не знаю, как получить к нему доступ из свойства, чтобы приведенная выше переменная "reg5" работала правильно.
Было бы замечательно, если бы был какой-то магический атрибут, который я мог бы просто добавить к свойству, чтобы "автоматически выражать" свойство и сделать LinqToSql счастливым, вместо того, чтобы заключать его в выражение <...>
Хотел бы иметь возможность сделать это ...
public partial class ProductRegistration :IProduct
{
[Auto-Expression]
public string product_name
{
get { return this.Product.product_name; }
}
}
EDIT
Ссылка и ответ ниже работает. Круто, спасибо. 2-я часть моего вопроса, снова у меня есть 2 аналогичных утверждения, 1-е работает, 2-е не (ошибка «не поддерживается перевод в SQL»).
var reg = rs.ProductRegistrations().ProductName("ACE").WithTranslations().SingleOrDefault();
var reg2 = rs.ProductRegistrations2().ProductName("ACE").WithTranslations().SingleOrDefault();
Различие в том, что 1-й возвращает IQueryable конкретного класса"IQueryable [ProductRegistration]", тогда как 2-й возвращает IQueryable интерфейса"IQueryable [IProduct]». Я хотел бы использовать 2-й, потому что я могу дать интерфейс многим различным классам, и это более общий способ, но, похоже, он не работает. Есть идеи?