[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; }
    }
}
執行結果:
