2012-07-10 73 views
1

假設你有一個ID列表:LINQ LEFT JOIN與列表<String>

string str = "82174F2000000, 82174F2000001, 82174F2000002, 82174F2000003, 82174F2000004, 82174F2000005"; 

而且你這樣做:

var tids = new List<string>(str.Replace(", ", ",").Split(',')); 
var tntable = tids.AsQueryable(); 

而且要將其與左比較表中加入:

var line = from c in db.Ctable 
join l in tntable on c.CarID equals l.CarID into c_j 
    from l in c_j.DefaultIfEmpty() 
    select new 
    { 
Name = c.OwnerName, 
Hours = c.Hours 
    }; 

看起來像tntable沒有名爲'CarID'的字段。

有人可以幫忙嗎?

這是針對LINQ to Entity的。

我已經看到了這一點:

How to compare List<String> to DB Table using LINQ

但不知道做一個LEFT JOIN。

TIA!

我知道這很長;但感謝閱讀。

更新的MichaC:

在CTable的數據庫中,我們有這些CarIDs:

CarID 
_____ 
82174F2000000 
82174F2000001 
82174F2000002 
82174F2000003 

讓我們只說表(tntable)含有分解成記錄的字符串:

CarID 
_____ 
82174F2000000 
82174F2000001 
82174F2000002 
82174F2000003 
82174F2000004 
82174F2000005 

所以,一個左加入像這樣:

SELECT C.CarID, T.CarID 
FROM CTable C 
LEFT JOIN tntable T ON C.CarID = T.CarID 

會產生你:

T.CarID   C.CarID 
_______   _______ 
82174F2000000 82174F2000000 
82174F2000001 82174F2000001 
82174F2000002 82174F2000002 
82174F2000003 82174F2000003 
82174F2000004 NULL 
82174F2000005 NULL 

回答

1

如果我讀你的問題的權利,它看起來像你想的基於ID的列表來過濾,不執行左連接。我認爲你想要這樣的事情:

var line = from c in db.Ctable 
      where tntable.Contains(c.CarID) 
      select new 
      { 
       Name = c.OwnerName, 
       Hours = c.Hours 
      }; 

更新:您可以將包含檢查移動到select語句以返回所有內容。

var line = from c in db.Ctable 
      select new 
      { 
       IsMatch = tntable.Contains(c.CarID), 
       Name = c.OwnerName, 
       Hours = c.Hours 
      }; 

更新2:好的這個怎麼樣。使用我的原始從SQL中提取相關項目,然後使用Linq到對象來按照自己想要的方式實際構建列表。 .ToList()強制它進行SQL查詢。你也可以使用.AsEnumerable()。

var filtered = from c in db.Ctable 
      where tntable.Contains(c.CarID) 
      select new 
      { 
       CarID = c.CarID, 
       Name = c.OwnerName, 
       Hours = c.Hours 
      }; 

var line = from x in tntable 
      join i in filtered.ToList() on x equals u.CarID into i_match 
      from i in i_match.DefaultIfEmpty() 
      select { x, i }; 
+0

我不僅想知道CTable中的內容,而且還想返回NULL(不在CTable中)。你有的例子只返回CTable中的內容。謝謝! – scv 2012-07-10 00:46:54

+0

如果它有效,它非常酷。我會立即嘗試並報告。 – scv 2012-07-10 21:36:35

+0

看起來你有很好的chakara。再次感謝。 – scv 2012-07-10 23:29:46

0

從您發表評論希望NULL還是選擇即使ID不在ctable發現在tntable每個ID的對象?如果我理解正確的話,我相信這會給你想要的效果。

var desired = from l in tntable 
       join c in ctable on l equals c.CarID into lj 
       from c in lj.DefaultIfEmpty() 
       select 
        new 
         { 
          Name = c == null ? null : c.OwnerName, 
          Hours = c == null ? (int?)null : c.Hours 
         }; 
+0

錯誤是'l.CarID'b/c tntable沒有名爲'CarID'的字段。所以我想我必須創建一個名爲'CarID'的字段的Model(類),然後執行列表 table2 = new List ();然後將字符串中的每個值添加到它中。這有意義嗎?謝謝! – scv 2012-07-10 01:32:40

+0

啊我是測試這與LINQ到對象,它在那裏工作很好,我不能再現您創建數據庫模型時出現的特定錯誤我得到的錯誤更加神祕(此方法支持LINQ to Entities基礎結構,並且不打算直接從你的代碼中使用)。我顯然不太瞭解Entity Framework來提供您的答案。抱歉。 – vossad01 2012-07-10 02:10:55

+0

感謝vossad01甚至嘗試;但你知道我喜歡你的NULL。再次感謝。 – scv 2012-07-10 02:57:20

0

在此看一看:

string str = "Pat, Boots"; 
var names = new List<string>(str.Replace(", ", ",").Split(',')).AsQueryable(); 

Pet defaultPet = new Pet { Name = "Default Pet", Age = -1 }; 

List<Pet> pets1 = new List<Pet>{ 
      new Pet { Name="Barley", Age=8 }, 
      new Pet { Name="Boots", Age=4 }, 
      new Pet { Name="Whiskers", Age=1 } 
    }; 

var pets = from name in names 
      join pet in pets1 on name equals pet.Name into gj 
      from subpet in gj.DefaultIfEmpty(defaultPet) 
      select new { Name = name, Age = subpet.Age }; 


foreach(var newPet in pets) { 
    Console.WriteLine("\nName: {0}, Age: {1} ", newPet.Name, newPet.Age); 
} 

這將產生:

Name: Pat, Age: -1 
Name: Boots, Age: 4 

如果不這樣做你想要什麼,然後有在How to: Perform Left Outer Joins (C# Programming Guide) on MSDN仔細看看。

我對DefaultIfEmpty()使用了上面的鏈接和MSDN的幫助頁面。

+0

謝謝泰米克。我不在一臺可以運行你的例子的電腦上;但它看起來可以用於鏈接到對象。你有沒有試圖查詢一個數據庫中的表,並留下連接到一個字符串(非數據庫)?我很確定這是一個非常普遍的任務。用戶鍵入一堆文本,並確定它們是否在表格中。謝謝! – scv 2012-07-10 09:06:54

+0

如果你去MSDN論壇並在linq +上進行搜索+實體+左+加入+字符串或LINQ +到+實體+字符串,你會得到1帖子。 – scv 2012-07-10 18:05:50