Подтвердить что ты не робот

Разница между == и .Equals() с интерфейсами и LINQ

Недавно я получил сообщение об ошибке "Отображение элемента интерфейса..... не поддерживается", которое я решил на основе этот поток, Чтобы продемонстрировать:

public interface IMyInterface { string valueText { get; set; } }
public class MyData : IMyInterface
{
   int ID { get; set;}
   string valueText { get; set;}
}
public class MyOtherData : IMyInterface
{
   long ID { get; set;}
   string valueText { get; set;}
}

и

public static IEnumerable<T> GetByValue<T>(string value) : where T : class, IMyInterface, new()
{ 
   using (var context = new DataContext())
   { 
      // The important line
      return context.GetTable<T>().Where(x => x.valueText == value);
   }
}

Запустив этот код, я бы получил NotSupportedException: "Отображение элемента интерфейса IMyInterface.valueText не поддерживается". Однако, если я заменяю x.valueText == value на x.valueText.Equals(value), это работает полностью, как ожидалось.

Я решил это в своем коде, но я хочу понять, почему он ведет себя таким образом. Кто-нибудь может объяснить это?

Обновление:. В соответствии с моим комментарием ниже команда LINQ to SQL закрыла это как "Не исправить". Я думаю, это означает, что теперь он считается известной ошибкой, но тот, который не будет разрешен в ближайшее время. Мне все равно хотелось бы знать, почему это происходит по-разному, однако.

4b9b3361

Ответ 1

По-видимому, решение направить запрос вверх на сервер производится на основе неполного набора правил, а затем LINQ-to-SQL находит конструкцию (интерфейс), с которой она не может справиться.

Вызов метода не поддерживается LINQ-to-SQL, поэтому он генерирует запрос для извлечения всех записей, а затем использует LINQ-to-Objects для их фильтрации. (На самом деле, в зависимости от вашего другого потока, LINQ-to-SQL может сделать специальное исключение для object.Equals и знает, как его преобразовать в SQL).

LINQ-to-SQL, вероятно, должен вернуться к поведению LINQ-to-Objects при взаимодействии с интерфейсом, но, по-видимому, он просто генерирует исключение.