zoukankan      html  css  js  c++  java
  • Lamda 表达式里的Join和GroupJoin的区别, 如何实现SQL的Left Join效果

    例如,可以将产品表与产品类别表相联接,得到产品名称和与其相对应的类别名称

    复制代码
    db.Products  
    .Join  
     (  
          db.Categories,  
          p => p.CategoryID,  
          c => c.CategoryID,  
          (p, c) => new {p,c.CategoryName}  
    )  
    .Where(p => p.CategoryID == 1);  
    复制代码

    这个Join对应SQL里的inner Join, 这个很容易理解. 上面代码里红色的c的类型是Category

    如果我要达到SQL里Left Join的效果, 该怎么写呢? 想当然的以为,把Join改成GroupJoin,

    复制代码
    db.Products  
    .GroupJoin  
     (  
          db.Categories,  
          p => p.CategoryID,  
          c => c.CategoryID,  
          (p, cs) => new {p,cs.FirstOrDefault().CategoryName} 
    )  
    .Where(p => p.CategoryID == 1);  
    复制代码

    上面代码里红色的cs的类型是IEnumerable<Category>, 你用FirstOrDefault()只是拿到一个目录,万一Product Left join是有多个目录呢?

    所以要用.SelectMany把IEnumerable<Category> 把里面的每一个元素做投影.

    要注意加上DefaultIfEmtyp() 才是Left join, 假如没有加这个,还是Inner Join

    复制代码
    db.Products
    .GroupJoin(db.Categories,
              (Product p) => p.CategoryId,
              (Category c) => c.CategoryId,
              (prod, cs) => new { prod, cs }) // cs is IEnumerable<Category>
              .SelectMany(prodCats => prodCats.cs.DefaultIfEmpty(), (prodCats, c) =>
                                    new
                                    {
                                        prodCats.prod
                                        categoryName = c.CategoryName
                                    });
    复制代码

    用LinQ query表达式 对应的写法是

    复制代码
                var qry =
                from p in db.Products
                join c in db.Categories on  p.CategoryId equals c.CategoryId
                into g from pc in g.DefaultIfEmpty()
                select new { 
                        prodId = p.ProdId,
                        prodCode = p.ProdCode,
                        prodName = p.ProdName,
                        categoryName = g.FirstOrDefault().CategoryName
                };
    复制代码

    如果我只用DefaultIfEmpty(),不用GroupJoin,这样写能达到这个效果吗?

    复制代码
                var qry = db.Products.SelectMany
                (
                    p => db.Categories.Where(c => c.CategoryId == p.CategoryId).DefaultIfEmpty(),
                    (p, c) => new
                    {
                        p.ProdId,
                        p.ProdCode,
                        p.ProdName,
                        c.CategoryName
                    }
                );
    复制代码

    这样写,如果数据量大,性能会很差. 因为它会把Products和Categories都Load到内存里,再Match, 而不是用SQL Left Join

    参考文章: 

    https://stackoverflow.com/questions/584820/how-do-you-perform-a-left-outer-join-using-linq-extension-methods

    http://linqsamples.com/linq-to-objects/join/GroupJoin-linq

    https://docs.microsoft.com/en-us/dotnet/csharp/linq/perform-left-outer-joins 

  • 相关阅读:
    1052 Linked List Sorting (25 分)
    1051 Pop Sequence (25 分)
    1050 String Subtraction (20 分)
    1049 Counting Ones (30 分)
    1048 Find Coins (25 分)
    1047 Student List for Course (25 分)
    1046 Shortest Distance (20 分)
    1045 Favorite Color Stripe (30 分)
    1044 Shopping in Mars (25 分)
    1055 The World's Richest (25 分)
  • 原文地址:https://www.cnblogs.com/Jayesslee/p/9306328.html
Copyright © 2011-2022 走看看