Получение неверного результата при выполнении левого внешнего соединения с использованием Linq-Why? - PullRequest
1 голос
/ 18 февраля 2012

У меня есть следующее

public class Person
    { 
        // Properties
        public string Name { get; set; }
        public string Area { get; set; }
        public string Gender { get; set; }
        public int Age { get; set; }

        public List<Person> GetPersonData()
        {
            List<Person> personLst = new List<Person>  {
           new Person { Name="Shashidhar Niketani", Age=20, Gender="Male" , Area = "Assam"},
           new Person { Name="Ahmed Ali Khan", Age=25 ,Gender="Male", Area = "Assam" },
           new Person { Name="S. Mirja", Age=20, Gender="Female", Area = "Assam"},
           new Person { Name="Neru Kumar", Age=18, Gender="Female", Area = "Colombo"},
           new Person { Name="Chidam P", Age=19, Gender="Male", Area = "Colombo"},
           new Person { Name="H Kontala", Age=19, Gender="Male", Area = "Bombay"},
           new Person { Name="Priya Pankhraj", Age=23, Gender="Female", Area = "North Punjab"},
             new Person { Name="Ambla", Age=20, Gender="Female", Area = "Madras"},
           new Person { Name="H Kontala", Age=25, Gender="Male", Area = "Bombay"},
           new Person { Name="Sirisha Chalukuri", Age=30, Gender="Female", Area = "Bombay"}};
            return personLst;
        }

        public override string ToString()
        {
            return string.Format("Patient Name: =  {0} , Age:= {1}, Gender:= {2}, Area: = {3}", Name, Age, Gender, Area);
        }

    }

    public class Hobbies
    {
        public string Owner { get; set; }
        public string HobbyName { get; set; }

        public List<Hobbies> GetHobbies()
        {
            List<Hobbies> hobbyList = new List<Hobbies>  {
           new Hobbies { Owner="Sirisha Chalukuri", HobbyName = "Singing"},
           new Hobbies { Owner="Priya Pankhraj", HobbyName = "Cooking" },
           new Hobbies { Owner="S. Mirja", HobbyName="Playing"},
           new Hobbies { Owner="Neru Kumar", HobbyName="Programing"}};
           return hobbyList;
        }
    }

Я пытаюсь выполнить левое соединение

// получить эти записи

Person p = new Person();
var personSource = p.GetPersonData();

Hobbies h = new Hobbies();
var hobbySource = h.GetHobbies();

// Левое внешнее соединение

var res8 = (from person in personSource                       
                        join hobby in hobbySource
                        on p.Name equals hobby.Owner into temp
                        from hobby in temp.DefaultIfEmpty()
                        select new
                            {
                                PersonName = p.Name,
                                PersonAge = p.Age,
                                Gender = p.Gender,
                                LivesIn = p.Area,
                                Hobby = (hobby == null) ? "N/A" : hobby.HobbyName
                            });

Но я не могу получить правильный результат ... Все записи поступают в виде нулевых / не совпадающих записей. По крайней мере 4 совпадающих записи, а остальные будут несовпадающими...

Я предпочитаю искать, учитывая эти два источника данных, результат, который мы ожидаем, если выполним левое соединение с PersonName и HobbyOwner.

Требуется помощь

Ответы [ 3 ]

1 голос
/ 18 февраля 2012

Когда вы ссылаетесь на hobby.HobbyName в выбранной вами проекции, hobby равно нулю, когда нет соответствующих увлечений для человека (DefaultIfEmpty возвращает null для пустой коллекции хобби).Вам нужно проверить, является ли хобби пустым, и, если это так, назначить свойству Хобби в проекции выбора значение по умолчанию.Например:

select new
{
  PersonName = p.Name,
  PersonAge = p.Age,
  Gender = p.Gender,
  LivesIn = p.Area,
  Hobby = (hobby == null) ? "N/A" : hobby.HobbyName
});

Кроме того, не знаю, была ли это опечатка, но в своем запросе вы используете p, когда вам нужно использовать person:

var res8 = (from person in personSource                       
        join hobby in hobbySource
        on person.Name equals hobby.Owner into temp
        from hobby in temp.DefaultIfEmpty()
        select new
        {
         PersonName = person.Name,
         PersonAge = person.Age,
         Gender = person.Gender,
         LivesIn = person.Area,
         Hobby = (hobby == null) ? "N/A" : hobby.HobbyName
         });
0 голосов
/ 18 февраля 2012

Единственное, что мне нужно было сделать с вашим кодом, чтобы заставить его работать, это изменять каждое вхождение с p на person в вашем последнем блоке (и только ваш последний блок, который я скопировал, модифицировал и вставил ниже) :

var res8 = (from person in personSource
                    join hobby in hobbySource
                    on person.Name equals hobby.Owner into temp
                    from hobby in temp.DefaultIfEmpty()
                    select new {
                        PersonName = person.Name,
                        PersonAge = person.Age,
                        Gender = person.Gender,
                        LivesIn = person.Area,
                        Hobby = (hobby == null) ? "N/A" : hobby.HobbyName
                    });

Кроме того, я не знаю, насколько этот код похож на ваш реальный код, но ваши функции GetPersonData () и GetHobbies () имеют больше смысла как статические методы. Таким образом, вам не нужно создавать бесполезный экземпляр Person или Hobbies только для того, чтобы получить свой список. Похоже, что p Персонаж там сбил тебя с толку.

0 голосов
/ 18 февраля 2012

По определению левое внешнее объединение будет извлекать все записи из первой коллекции, независимо от того, существует ли соответствующая запись в правой коллекции или нет.

Я думаю, что вы ищете:

var res8 = (from person in personSource                       
                        join hobby in hobbySource
                        on p.Name equals hobby.Owner into temp
                        from hobby in temp.DefaultIfEmpty()
                        select new
                            {
                                PersonName = p.Name,
                                PersonAge = p.Age,
                                Gender = p.Gender,
                                LivesIn = p.Area,
                                Hobby = hobby == null ? null : hobby.HobbyName
                            });
...