2013-04-27 82 views
5

嗨,我有下面的代碼在其他表中選擇一個表沒有數據LINQ到不能在其它表中選擇一個表數據

var result1 = (from e in db.Users 
       select e).ToList(); 
var result2 = (from e in db.Fi 
       select e).ToList(); 
List<string> listString = (from e in result1 
          where !(from m in result2 
            select m.UserID).Contains(e.UserID) 
          select e.UserName).ToList(); 

ViewBag.ddlUserId = listString; 

我得到裏面的值listString。但同時增加listString到了錯誤viewbag。

Unable to cast object of type 'System.Collections.Generic.List`1[System.String]' to type 'System.Collections.Generic.IEnumerable`1[Main.Models.Admin.User]'. 
+0

檢查'ddlUserId'的數據類型,可能與字符串不匹配! – zey 2013-04-27 05:40:01

+0

看起來像ViewBag.ddlUserId期望一個IEnumerable的User對象。但查詢的結果是字符串列表 – 2013-04-27 06:52:35

+0

我認爲管理員用戶是一個枚舉。 – Amit 2013-04-27 07:07:10

回答

15

首先,你能否用整個方法更新你的問題,以便我們看到ViewBag會發生什麼?因爲你的代碼應該工作得很好,所以爲ViewBag分配任何值通常都是沒有問題的:

ViewBag.property1 = 0; 
    ViewBag.property1 = "zero"; 

工作得很好。 ViewBag是動態的。現在,如果您稍後嘗試將ViewBag.ddlUserId分配給實際爲錯誤類型的東西,則可能會出現該錯誤。

我想你也重寫你的陳述,讓我解釋一下爲什麼。假設您的db.Users中有很多(> 100.000)User記錄,並且我們假設Fi也是如此。在您的代碼中,result1result2現在是兩個列表,其中一個包含> 100.000 User對象,另一個包含100.000 Fi個對象。然後將這兩個列表進行比較以產生一個字符串列表。現在想象一下你的Web服務器處理這個所需的資源。假設你實際使用/訪問單獨的SQL服務器來檢索你的數據,讓這個服務器完成這項工作,比如產生UserID列表,會更好更快。 對於你要麼使用基里爾Bestemyanov的答案或以下:

var list = (from user in db.Users 
       where !db.Fi.Any(f => f.UserID == user.UserID) 
       select user.UserName).ToList() 

這將產生SQL服務器只是一個查詢來執行:

SELECT 
    [Extent1].[UserName] AS [UserName] 
    FROM [dbo].[Users] AS [Extent1] 
    WHERE NOT EXISTS (SELECT 
     1 AS [C1] 
    FROM [dbo].[Fi] AS [Extent2] 
    WHERE [Extent2].[UserID] = [Extent1].[UserID] 
    )} 

這到底是你想要什麼...

只是爲了澄清更多:

var list = (from user in db.Users 
       where !db.Fi.Any(f => f.UserID == user.UserID) 
       select user.UserName).ToList() 

可以寫成以下lambda表達式,以及:

var list = db.Users.Where(user => !db.Fi.Any(f => f.UserID == user.UserID)) 
       .Select(user => user.UserName).ToList() 

從它的外觀是由基里爾Bestemyanov的回答略有不同(我略作修改,只是爲了讓它看起來更加類似):

var list = db.Users.Where(user => !db.Fi.Select(f => f.UserID) 
              .Contains(user.UserID)) 
           .Select(user => user.UserName).ToList(); 

但是,它們實際上會產生相同的SQL語句,因此也是相同的列表。

3

我將它改寫爲LINQ擴展方法:

List<string> listString = db.Users.Where(e=>!db.Fi.Select(m=>m.UserID) 
                .Contains(e.UserID)) 
            .Select(e=>e.UserName).ToList(); 

試試吧,它應該工作。

+0

我擔心這會產生一堆SQL調用,但它將其轉換爲正確的SQL謝謝! – Nico 2017-04-05 17:41:15

4

試試這個很簡單。

var result=(from e in db.Users 
      select e.UserID).Except(from m in db.Fi 
            select m.UserID).ToList(); 
相關問題