Список внутри объекта IQueryable

Учитывая следующее:

public class Person
{
  public int ID { get; set;}
  public string Name { get; set;}
  public IQueryable<Pet> Pets { get;set; }
}

public class Pet
{
  public int id { get; set; }
  public int OwnerId { get; set; }
  public string Name { get; set; }
}

public class SearchCriteria
{
  public string PersonName {get; set; }
  public List<string> PetNames {get; set;}
}

Реализация выбора всех лиц с их домашними животными при поиске с помощью IQueryable

public List<Person> GetWithPets(SearchCriteria search)
{
     var people = (from p in context.People
                   where p.Name == search.PersonName
                   select new Person{
                          ID = p.ID,
                        Name = p.Name,
                        Pets = (from pt in context.Pets
                                where pt.OwnerId == p.ID
                                select new Pet {
                                   id = pt.ID,
                                 OwnerId = pt.OwnerId,
                                 Name = pt.Name
                                }).AsQueryable
                   }).AsQueryable();

       foreach(var str in search.PetNames)
       {
            people = people.Where(o=>o.Pets.Any(p=>p.Name == str));
       }
  return people.ToList();
}

Моя проблема в том, что независимо от foreach, который ищет имя, в возвращаемом списке людей домашние животные пусты, даже если есть домашние животные, связанные с этим человеком, где я ошибся?

ИЗМЕНИТЬ:

public class Person
{
    public int ID { get; set; }
    public string Name { get; set; }
    public IQueryable<Animal> Pets { get; set; }
}

public class Animal
{
    public int id { get; set; }
    public int? OwnerId { get; set; }
    public string Name { get; set; }
}

public class SearchCriteria
{
    public string PersonName { get; set; }
    public List<string> PetNames { get; set; }
}



class Program
{
    public static List<Person> GetWithPets(SearchCriteria search)
    {
        using (DatabaseEntities context = new DatabaseEntities())
        {
            var people = (from p in context.Peoples
                          where p.Name == search.PersonName
                          select new Person
                          {
                              ID = p.ID,
                              Name = p.Name,
                              Pets = (from pt in context.Pets
                                      where pt.OwnerID == p.ID
                                      select new Animal
                                      {
                                          id = pt.ID,
                                          OwnerId = pt.OwnerID,
                                          Name = pt.Name
                                      }).AsQueryable()
                          }).AsQueryable();

            foreach (var str in search.PetNames)
            {
                people = people.Where(o => o.Pets.Any(p => p.Name == str));
            }
            return people.ToList();
        }
    }

person Rami Sakr    schedule 04.04.2012    source источник
comment
что должен вернуть ваш метод? Список людей с Name равным search.PersonName и с любым питомцем, чье имя находится в search.PetNames?   -  person Bazzz    schedule 04.04.2012
comment
мой метод должен возвращать список людей, имя которых равно search.PersonName и ВСЕХ их питомцев, но только тех людей, у которых есть питомцы с этими именами в search.PetNames   -  person Rami Sakr    schedule 04.04.2012
comment
Объекты Person и Pet сопоставляются с БД или это только вспомогательные классы для получения результата поиска? Что произойдет, если вы удалите цикл foreach? Pets все еще null?   -  person Slauma    schedule 04.04.2012
comment
Нет, Person и Pet - это просто классы, которые я создал, они сопоставляются с людьми и домашними животными в сущностях. Если я удалю foreach Pets, все равно будет null..   -  person Rami Sakr    schedule 04.04.2012
comment
Является ли List<Pet> Pets действительно личным? Я не знаю, как вы могли установить частное свойство в выбранной проекции. Кроме того, результатом внутреннего from... является IQueryable<Pet>, как вы можете назначить его List<Pet>, вы должны получить ошибку компилятора.   -  person Slauma    schedule 04.04.2012
comment
@Saluma У него должна была быть ошибка времени компиляции для people.Where(o=>o.Pets.Any(p=>p == str));, поскольку p имеет тип Pet, а str - это string! Я думаю, это всего лишь псевдокод   -  person Flowerking    schedule 04.04.2012
comment
@Flowerking: Да, и это тоже! Вопрос должен быть действительно привязан к реальному (компилируемому) коду, иначе полезного ответа не будет.   -  person Slauma    schedule 04.04.2012
comment
@Slauma Я написал это прямо в редакторе, а не в Visual Studio, во всяком случае, синтаксис не проверял, я отредактировал вопрос ...   -  person Rami Sakr    schedule 04.04.2012
comment
@RamiSakr: он все еще не может скомпилироваться, потому что внутренний from... возвращает IQueryable<Pet>, и вы не можете назначить это List<Pet> (как уже было сказано выше). И этот фрагмент — самая важная часть вашего вопроса, он должен быть точно вашим настоящим кодом.   -  person Slauma    schedule 04.04.2012
comment
@Slauma, пожалуйста, проверьте отредактированный вопрос еще раз ... Я повторно отредактировал вопрос и преобразовал свой список в IQueryable.   -  person Rami Sakr    schedule 04.04.2012
comment
Ваш код очень сбивает с толку: Pets действительно не может быть null, если это IQueryable. Результатом может быть пустая коллекция, но не null. Можете ли вы тщательно проверить, является ли это настоящим кодом, который вы используете? Почему-то после всех правок я все еще не доверяю вашему коду.   -  person Slauma    schedule 04.04.2012


Ответы (4)


Если Person и Pet являются объектами вашей модели и если Person.Pets является свойством навигации для объекта Pet и если вы хотите иметь полный Person сущность со всеми полными Pet сущностями и ссылаясь на ваш комментарий...

мой метод должен возвращать список людей, имя которых равно search.PersonName и ВСЕХ их питомцев, но только тех людей, у которых есть питомцы с этими именами в search.PetNames

... вы можете использовать это:

public List<Person> GetWithPets(SearchCriteria search)
{
    var people = from p in context.People.Include("Pets")
                 where p.Name == search.PersonName
                    && p.Pets.Any(pt => search.PetNames.Contains(pt.Name))
                 select p;

    return people.ToList();
}
person Slauma    schedule 04.04.2012

Или вы можете попробовать что-то вроде этого

foreach(var str in search.PetNames)
       {
            people.Concat(people.Where(o=>o.Pets.Any(p=>p == str)).Include('Pet'));
       }
person Jayanga    schedule 04.04.2012
comment
@Jayanga Вы должны отредактировать свой другой ответ, а не добавлять другой ответ. - person Raj Ranjhan; 04.04.2012

Можете ли вы попробовать что-то вроде этого

var people = (from p in context.People
                   where p.Name == search.PersonName
                   select new Person{
                          ID = p.ID,
                        Name = p.Name,
                        Pets = (from pt in context.Pets
                                where pt.OwnerId == p.ID
                                select new Pet {
                                   id = pt.ID,
                                 OwnerId = pt.OwnerId,
                                 Name = pt.Name
                                })
                   }).Include("Pets").AsQueryable();
person Jayanga    schedule 04.04.2012

Добавить AsQueryable() в коллекцию Pets:

Pets = (from pt in context.Pets  
        where pt.OwnerId == p.ID  
        select new Pet {  
            id = pt.ID,  
            OwnerId = pt.OwnerId,  
            Name = pt.Name  
        }).AsQuerable() 
person RePierre    schedule 04.04.2012
comment
Не работает, я пробовал. Невозможно неявно преобразовать тип «System.Linq.IQueryable‹Pet›» в «System.Collections.Generic.List‹Pet›», который находится в моем общедоступном классе Person {public int ID {get; установить;} публичное имя строки {получить; set;} List‹Pet› Домашние животные { get;set; } } - person Rami Sakr; 04.04.2012
comment
@RamiSakr, глядя на сообщение об ошибке, я предлагаю заменить AsQuerable() на Pets на ToList() Pets = (from pt in context.Pets where pt.OwnerId == p.ID select new Pet { id = pt.ID, OwnerId = pt.OwnerId, Name = pt.Name }).ToList() - person RePierre; 05.04.2012