Linq To EF: Как фильтровать, используя не примитивные типы - PullRequest
3 голосов
/ 20 апреля 2011
public class Person
{
   public int ID { get; set; }
   public int Job { get; set; }
   public string Name { get; set; }
}

List<Person> personsOfInterest = GetPersonsOfInterest();

PersonEntities personEntities = new PersonEntities();

var filteredPersons = personEntities.Where(p => personsOfInterest.Any(poi => poi.Job == p.Job && poi.Name == p.Name));

Приведенный выше код генерирует NotSupportedException, поскольку Linq to Entities не поддерживает ссылки на нескалярные переменные (Person).

как я могу решить это? спасибо!

// edit: я пытаюсь найти людей из personEntities, которые имеют то же имя и ту же работу, что и все остальные, в списке personOfInterest. например, я пытаюсь найти кого-то в моем лице, который является полицейским по имени Боб или программистом по имени Джон.
ошибка, которую я получаю, описана в здесь . (22.2)

Ответы [ 2 ]

2 голосов
/ 21 апреля 2011

Прежде всего обе коллекции должны содержать объекты одного типа.

Тогда вы можете сделать следующее:

    var filteredPerosns = personEntities
          .Where(p => personsOfInterest.Contains(p, new MyPersonComparer()));

создать класс:

    class MyPersonComparer : IEqualityComparer<Person>
    {
        public bool Equals(Person x, Person y)
        {
            return x.Job == y.Job && x.Name == y.Name; 
        }

        public int GetHashCode(Person obj)
        {
            return obj.PersonID; //Just for example...
        }
    }

ИЛИ , если первое не является опцией, вы можете выполнить объединение чего-либо по линии (в концепции):

    List<int?> listA = new List<int?>() {1, 2, 3, 4, 5, 6, 7};
    List<int?> listB = new List<int?>() {5};

    bool result = (from a in listA
                   join b in listB on a equals b 
                   select a).Any();

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

РЕДАКТИРОВАНИЕ: Я изменил приведенный выше пример, чтобы отразить ваше отредактированное описание:

    List<Person> personsOfInterest = GetPersonsOfInterest();

    var filteredPersons = (from a in personEntities
           join b in personsOfInterest on new{a.Name, a.Job} equals new {b.Name, b.Job} 
           select a).ToList();

PersonEntities в вашем коде, это пользовательский тип коллекции или это табличный / сложный тип в вашей модели EF?

1 голос
/ 21 апреля 2011

Лучше сравнить идентификаторы, а не объекты. Это будет намного эффективнее. Проблема в том, что EntityFramework не переводит obj1 == obj2 в SQL.

...