2016-07-28 7 views
0

У меня возникла следующая проблема: Я хочу загрузить один Список, но могу передать несколько параметров, какими могут быть критерии для поиска списков, которые я хочу. Теперь у меня есть следующая структура:C# linq с двумя списками

House{ 
    Name; 
    ID; 
    Alias; 
} 

Также я:

Person{ 
    Name; 
    Alias; 
} 

Это означает, что 1 дом может содержать несколько лиц и несколько человек с таким же именем может быть в нескольких домах. Итак, теперь я хочу назвать свою функцию e.G. «GetHouses (критерии строка)» в качестве критериев могут быть:

  1. имя дома
  2. идентификатор дома
  3. часть имени дома
  4. имя одного из Лица в доме

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

ВАЖНОЕ ПРИМЕЧАНИЕ: Я не могу изменить логику, пока здесь!

Итак, теперь, когда я пытаюсь найти подходящие критерии, я придумал использовать LINQ, поскольку он очень быстрый. Он работает до тех пор, пока я не сравнить с людьми:

result = (from x in result 
where (
    (string.Equals(x.Name, criteria)) 
    || (string.Equals(x.ID, criteria)) 
    || (x.Name.Contains(criteria)) 
    select x).ToList(); 

Теперь я хочу, чтобы загрузить каждый человек в домах, которые я нашел и проверить, является ли имя лиц в доме будет соответствовать критериям. Есть ли способ сделать это в LINQ, который у меня уже есть? Или я должен идти, хотя результат с:

result.ForEach(x => ...) 

Было бы хорошо, если он будет работать с LINQ. я сделал подобную логику с

result.FindAll(new Predicate<House>((x) => { ... LoadPersons(criteria) {... } })); 

Но что взял долго.

С наилучшими пожеланиями, Asat0r

+0

вы не просто пытались связывающими два элемента в LINQ ? а не foreach – BugFinder

+0

Как дом связан с человеком? Вы хотите «загрузить» людей в соответствующие дома, которые имеют одинаковые критерии соответствия? Если да, то что, если один человек может соответствовать многим домам? –

+0

Не должен ли класс дома содержать в нем список лиц? – OrMiz

ответ

1

Предположив, что у вас есть в вашем House в PersonList -класса можно использовать Enumerable.Any:

var matchingHouses = from house in allHouses 
    where string.Equals(house.Name, criteria) 
     || string.Equals(house.ID, criteria) 
     || house.Name.Contains(criteria) 
     || house.PersonList.Any(resident => string.Equals(resident.Name, criteria)) 
    select house; 

Если у вас есть метод, чтобы вернуть «резиденты» вы можете использовать это. Если позже вы хотите получить доступ к этим лицам, вы можете создать анонимный тип для их хранения:

var housesAndResidents = from house in allHouses 
    let matchingResidentList = LoadPersons(house.ID) 
     .Where(resident => string.Equals(resident.Name, criteria)) 
     .ToList() 
    where string.Equals(house.Name, criteria) 
     || string.Equals(house.ID, criteria) 
     || house.Name.Contains(criteria) 
     || matchingResidentList.Any() 
    select new { house, matchingResidentList }; 

Вы можете получить доступ к этим свойствам следующим образом:

var matchingHouseList = housesAndResidents.ToList(); 
// you don't need the list, you can use foreach directly, 
// but whenever you access housesAndResidents you will execute that query 
// ToList materializes this query into a collection, so you can enumerate it or use the Count property 
foreach(var x in matchingHouseList) 
{ 
    Console.WriteLine("House:{0} Matching-Resident(s):{1}" 
     , x.house.Name 
     , String.Join(", ", x.matchingResidentList.Select(r => r.Name))); 
} 
+0

Ну, это дало мне идею, хотя у меня нет класса в классе House, метод «LoadPersons()» возвращает список лиц, поэтому я добавил: «|| LoadPersons (x.ID). Любой (y => string.Equals (y.Name, criteria)) " Поскольку я могу загрузить только Лица, если я использую ID дома. Но это также занимает несколько раз. – Asat0r

+0

@ Asat0r: наверняка потребуется некоторое время, потому что этот запрос стоит дорого, но я не понимаю, как вы могли его улучшить. Мы слишком мало знаем о предпосылке, чтобы предложить что-нибудь лучше. –

+0

@ Asat0r: я показал второй подход, который использует этот метод и сохраняет его в анонимном типе. –

0

Вот простое решение с использованием трех классов : Program, House и Person.

Класс House «Дома» (каламбур) - список классов Person (и ваши собственные значения: имя, идентификатор и псевдоним). Таким образом, жители являются частью дома и не хранятся в другом месте. Хранение жителей за пределами класса House - это то же самое, что и содержимое вашего ланчбокса вне коробки в вашем рюкзаке.

В классе Person хранится основная информация о жильцах дома. Наличие списка жителей внутри класса House упрощает сравнение критериев поиска с людьми.

В классе Program вы найдете классы Main и FindHouses. Это своего рода объясняет себя

class Person 
{ 
    public string name; 
    public string alias; 

    public Person(string _name, string _alias = "") 
    { 
     name = _name; 
     alias = _alias; 
    } 
} 

class House 
{ 
    public string name; 
    public string id; 
    public string alias; 
    public List<Person> people = new List<Person>(); 

    public House(string _name, string _id, string _alias = "") 
    { 
     name = _name; 
     id = _id; 
     alias = _alias; 
    } 
} 

class Program 
{ 
    static List<House> houses = new List<House>(); 

    static void Main(string[] args) 
    { 
     // Add houses here 

     foreach (House house in FindHouses("criteria")) 
     { 
      // Do stuff 
     } 
    } 

    // Find all the houses in which the criteria exists 
    static List<House> FindHouses(string criteria) 
    { 
     // Return the list of all houses in which the criteria exists 
     return houses.Where(h => 
      h.name.Contains(criteria) || 
      h.id == criteria || 
      h.alias.Contains(criteria) || 

      h.people.Any(p => 
      p.name.Contains(criteria) || 
      p.alias.Contains(criteria))).ToList(); 
    } 
} 

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

Я знаю, что вы упомянули, что вы не хотите, чтобы загрузить человек в дома, но это делает поиск домов на основе «все значения» гораздо проще

Смежные вопросы