[C#] 利用 Linq 的 Full Outer Join 做資料的比對更新

  • 6548
  • 0
  • 2013-08-02

[C#] Linq 的 Full Outer Join

現在常寫Linq,卻常常記不起來Join語法

憤而記在部落格上,懶得再Google

Full Outer Join平常很少用,會用到,大都是要比對資料用

例如:Master Detail 一對多關聯的資料表

這種1對多關聯的資料表一般更新不外乎在Master表的編修流程做Delete Insert或先讓使用者進Detail更改資料後再讓他到Master更改資料

另一種在Master表的編修流程,就是用Full Outer Join

※2013.8.2 之前寫潦草,實際運用在專案上發現卡卡的,補上完整的Full Outer Join

 

原理

兩個集合分別先做Left Join和Right Join

之後用Union去除重覆的資料取聯集(不是Concat串連方法)

using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string sameGuid = "Same Guid";
            

           
            //使用者輸入的資料
            List<Product> inputProducts = new List<Product>(){ 
             new Product(){  ProductGuid=sameGuid, ProductName="A"}, 
             new Product(){  ProductGuid="aGuid", ProductName="a"}, 
            };

            //DB資料
            List<Product> dbProducts = new List<Product>(){ 
             new Product(){  ProductGuid=sameGuid, ProductName="B"}, 
             new Product(){  ProductGuid="bGuid", ProductName="b"}, 
            };



            var leftJoin = from input in inputProducts
                           join db in dbProducts
                           on input.ProductGuid equals db.ProductGuid into ps
                           from dbb in ps.DefaultIfEmpty(new Product() { ProductGuid="" })
                           select new
                           {
                               //Master Detail資料更新時,以使用者輸入的資料為主
                               inputProductGuid=  input.ProductGuid,
                               dbProductGuid =dbb.ProductGuid,
                               inputProductName = input.ProductName
                           };
            var rightJoin = from db in dbProducts
                            join input in inputProducts
                            on db.ProductGuid equals input.ProductGuid into ps
                            from inputt in ps.DefaultIfEmpty(new Product() { ProductGuid=""  })
                            select new
                            {
                                inputProductGuid = inputt.ProductGuid,
                                dbProductGuid = db.ProductGuid,
                                inputProductName = inputt.ProductName
                            };
             
            var result = leftJoin.Union(rightJoin);//取聯集,去除重覆 
             
            foreach (var item in result)
            {
                Console.WriteLine("inputProductGuid:"+item.inputProductGuid+"\t"+"dbProductGuid:"+item.dbProductGuid+"\t"+"inputProductName:"+item.inputProductName);
                if (item.inputProductGuid==item.dbProductGuid)
                {
                    Console.WriteLine("↑執行更新:"+"更新的商品名稱為:"+item.inputProductName);    
                }else if(item.inputProductName!="" && item.dbProductGuid=="")
                {
                    Console.WriteLine("↑執行新增:" + "新增的商品名稱為:" + item.inputProductName);    
                
                }else if (item.inputProductGuid=="" && item.dbProductGuid!="")
                {
                    Console.WriteLine("↑執行刪除:" + "刪除的商品Guid:" + item.dbProductGuid);    
                }
                 
                
            } 

            Console.ReadKey();
        }
    }
   
    class Product
    {
        public string ProductGuid { get; set; }
        public string ProductName { get; set; }

    }

}

執行結果:

image