LINQ Left Outer Синтаксическая разница JOIN - PullRequest
2 голосов
/ 22 июля 2011

В LINQ

есть как минимум два способа выполнить левое внешнее соединение.
class Customer
{
    public int ID { get; set; }
    public string Name { get; set; }
}

class Order
{
    public int ID { get; set; }
    public string Product { get; set; }
}

    static void Main()
    {
        // Example customers.
        var customers = new Customer[]
        {
            new Customer{ID = 5, Name = "Sam"},
            new Customer{ID = 6, Name = "Dave"},
            new Customer{ID = 7, Name = "Julia"},
            new Customer{ID = 8, Name = "Sue"},
            new Customer{ID = 9, Name = "Joe"}
        };

        // Example orders.
        var orders = new Order[]
        {
            new Order{ID = 5, Product = "Book"},
            new Order{ID = 6, Product = "Game"},
            new Order{ID = 7, Product = "Computer"},
            new Order{ID = 8, Product = "Shirt"},
            new Order{ID = 8, Product = "TShirt"}
        };


        // First Way
        var query = from c in customers
                join o in orders on c.ID equals o.ID into co
                from x in co.DefaultIfEmpty() 
                where x != null && x.Product == "Shirt"
                select new {c, x};

        // Second Way  
        var query2 = from c in customers
                     from o in orders
                     where c.ID == o.ID && o.Product == "Shirt"
                     select new {c, o};
    }

Я нашел много примеров First Way (используя 'into'), и именно так я делал свои ЛЕВЫЕ ВНЕШНИЕ СОЕДИНЕНИЯ. Недавно я нашел второй способ, и, похоже, он проще. Я проверил, и оба они дают одинаковый результат. Теперь мой вопрос: есть ли какие-то скрытые различия, производительность или это только синтаксический сахар?

Большое спасибо.

1 Ответ

6 голосов
/ 22 июля 2011

Первый способ следует использовать, если вы не используете проверку! = Null

Левое внешнее объединение выбирает все из левой таблицы со всеми элементами, которые соответствуют в правой таблице, если нет совпаденийсуществует в правой таблице, результат все еще возвращается, но для значений в правой таблице он равен нулю (linq переводит это значение по умолчанию для типа элемента коллекции)

Оба ваших запроса эффективно выполняют внутреннее соединение, поэтому они будутбыть одинаковыми.

Чтобы получить разные результаты

 // First Way
 var query = from c in customers
 join o in orders on c.ID equals o.ID into co
 from x in co.DefaultIfEmpty()
 where c.Id>5 
 select new {c, x};

 // Second Way
 var query2 = from c in customers
 from o in orders
 where c.ID == o.ID && c.ID > 5
 select new {c, o};
...