Why does Linq make the connection differently

OK, that’s a little moan, but that’s also a question. In Linq, I can do the following:

from c in dc.Customers join o in dc.Orders on c.custid equals o.custid ...

Everything is good, good and completely memorable, without having to go back and google. However, left joins are for some reason much more complicated:

from c in dc.Customers 
join o in dc.Orders on c.custid equals o.custid 
into temp from x in temp.DefaultIfEmpty() ...

So my question is: why can't Linq designers make things simple (more sql-like) with something like this:

from c in dc.Customers left join o to dc.Orders on c.custid equals o.custid ...

Cheers Lee

+5
source share
2 answers

why Linq designers can't make things simple (more sql like)

. ( sql) OO. Linq ( #) - OO. . # intellisense .

, , LEFT JOIN ( , LEFT OUTER JOIN), , - , ).

, , GROUP JOIN, .

List<int> myInts = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
List<int> myOtherInts = new List<int>() { 1, 3, 5, 7, 9, 11, 13 };
//
var query = from i in myInts
    join j in myOtherInts on i equals j into g
    select new {key = i, myGroup = g};
//
foreach (var grouping in query)
{
  Console.WriteLine("--{0}", grouping.key);
  foreach (var x in grouping.myGroup)
    Console.WriteLine(x);
}

, DefaultIfEmpty, - - / - . DefaultIfEmpty .

, :

var query = myInts.GroupJoin(
    myOtherInts,
    i => i,
    j => j,
    (i, g) => new { key = i, myGroup = g }
);

, ?

. . 50 1000 , 50 .

from c in dc.Customers
join o in dc.Orders on c.custid equals o.custid into someOrders
select new CustomerWithOrders()
  {theCustomer = c, theOrders = someOrders};

CustomerOrder. 5 , 5 , , . 0 , . 50 1000 , 50-1049 , .

from c in dc.Customers
join o in dc.Orders on c.custid equals o.custid into temp
from x in temp.DefaultIfEmpty()
select new CustomerOrderHybrid() {theCustomer = c, theOrder = x}

LEFT JOIN, . GROUP JOIN, , LEFT JOIN . .

+5

, Linq , . , - - .

SQL, , -. SQL- " ", , , .


, , , Linq, .

:

public class Class1
{
    public List<string> list = new List<string>() { "test", "test1", "test2" };

    public void test_lambda()
    {
        var test = list.Where(l => l == "test1");
    }

    public void test_linq()
    {
        var test = from l in list
                   where l == "test2"
                   select l;
    }
}

list.Where(l => l == "test2") , from l in list where l == "test2" select l. :

.method public hidebysig instance void test_lambda() cil managed
{
    .maxstack 8
    L_0000: ldarg.0 
    L_0001: ldfld class [mscorlib]System.Collections.Generic.List`1<string> Class1::list
    L_0006: ldsfld class [System.Core]System.Func`2<string, bool> Class1::CS$<>9__CachedAnonymousMethodDelegate1
    L_000b: brtrue.s L_001e
    L_000d: ldnull 
    L_000e: ldftn bool Class1::<test_lambda>b__0(string)
    L_0014: newobj instance void [System.Core]System.Func`2<string, bool>::.ctor(object, native int)
    L_0019: stsfld class [System.Core]System.Func`2<string, bool> Class1::CS$<>9__CachedAnonymousMethodDelegate1
    L_001e: ldsfld class [System.Core]System.Func`2<string, bool> Class1::CS$<>9__CachedAnonymousMethodDelegate1
    L_0023: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0> [System.Core]System.Linq.Enumerable::Where<string>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>, class [System.Core]System.Func`2<!!0, bool>)
    L_0028: pop 
    L_0029: ret 
}

.method public hidebysig instance void test_linq() cil managed
{
    .maxstack 8
    L_0000: ldarg.0 
    L_0001: ldfld class [mscorlib]System.Collections.Generic.List`1<string> Class1::list
    L_0006: ldsfld class [System.Core]System.Func`2<string, bool> Class1::CS$<>9__CachedAnonymousMethodDelegate3
    L_000b: brtrue.s L_001e
    L_000d: ldnull 
    L_000e: ldftn bool Class1::<test_linq>b__2(string)
    L_0014: newobj instance void [System.Core]System.Func`2<string, bool>::.ctor(object, native int)
    L_0019: stsfld class [System.Core]System.Func`2<string, bool> Class1::CS$<>9__CachedAnonymousMethodDelegate3
    L_001e: ldsfld class [System.Core]System.Func`2<string, bool> Class1::CS$<>9__CachedAnonymousMethodDelegate3
    L_0023: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0> [System.Core]System.Linq.Enumerable::Where<string>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>, class [System.Core]System.Func`2<!!0, bool>)
    L_0028: pop 
    L_0029: ret 
}

, . , .

0

All Articles