2013-04-27 81 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(); 
相关问题