LINQ-SQL - Использование статических полей только для чтения в CompiledQuery.Compile? - PullRequest
4 голосов
/ 01 ноября 2011

Я столкнулся со странной проблемой при использовании CompiledQuery.Compile. При попытке использовать статическое поле только для чтения в запросе я получаю следующее сообщение об ошибке:

Class member X is unmapped

Если я перенесу объявление поля из частичного класса в другой класс, не связанный с LINQ-SQL, то получу следующее:

Object reference not set to an instance of an object

Если я передаю поля в качестве аргумента, то не вижу ошибок, и запрос работает нормально и генерирует ожидаемый SQL.

Пример приведен ниже:

partial class Order 
{
    public static readonly string Complete = "Complete";
    public static readonly string Pending = "Pending";

    public static readonly Func<DataContext, Order, bool> IsComplete =
        CompiledQuery.Compile((DataContext context, Order o) =>
           Complete == o.Status);
}

Использование:

var test = from o in db.Orders
           select new
           {
               IsComplete = Order.IsComplete(db, o)
           };

Это приводит к указанным ошибкам. Если я добавлю string[] в качестве другого аргумента к CompiledQuery, я не увижу ошибок. Кроме того, если я изменяю строки на const вместо static readonly, это тоже работает, но я думаю, это связано со значениями, назначаемыми во время компиляции.

Есть ли способ заставить работать поля static readonly?

Ответы [ 2 ]

2 голосов
/ 01 ноября 2011

Проблема возникает из-за того, что Linq-To-Sql пытается преобразовать ваше выражение в внутренний SQL-код, поскольку логика видит несопоставленный член класса, который не может справиться с его преобразованием.

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

partial class Order  { 

  public static readonly string Complete = "Complete"; 
  public static readonly string Pending = "Pending"; 

  private static readonly Func<DataContext, Order, bool> _isComplete;

  public static Func<DataContext, Order, bool> IsComplete {
    get {
      if (_isComplete == null) {
        var complete=Complete; 
        _isComplete CompiledQuery.Compile((DataContext context, Order o) => 
                                                       complete == o.Status); 
      }
      return _isComplete;
    }
  }
}

}

0 голосов
/ 01 ноября 2011

Нет проблем, если вы не смешиваете обычные запросы и скомпилированные запросы.Следующее работает и даст вам лучшую производительность в целом, за счет невозможности повторного использования простого IsCompleted, скомпилированного где угодно.

public static readonly Func<YourDataContext, IEnumerable<Order>> GetCompletedOrders =
    CompiledQuery.Compile((YourDataContext context) =>
        context.Orders.Where(o => Complete == o.Status));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...