将DbSet和查询结果分配给同一个变量

时间:2015-12-22 11:25:05

标签: c# asp.net-mvc linq

我使用以下代码允许用户搜索其他注册用户,以便将其添加到好友列表中:

[Authorize(Roles = "RegisteredUsers")]
public ActionResult Index(string searchString)
{
    //list of registered users
    var regUsers = db.Users;

    if (!String.IsNullOrEmpty(searchString))
    {
        regUsers = regUsers.Where(s => s.User.LastName.Contains(searchString));
    }

    return View(regUsers.ToList());
}

然而,我在regUsers = regUsers.Where(..)的第9行收到错误,说明:

  

“无法隐式将System.Linq.IQueryable<ETLToolKit.Models.User>类型转换为System.Data.entity.DbSet<ETLToolKit.Models.User>

如何重用regUsers变量?

4 个答案:

答案 0 :(得分:6)

怎么样

Where

db.Users属于DbSet类型,因此当您进行regUsers调用时,它会尝试隐式地将不同类型的值分配给AsQueryable,这不起作用 - 因此错误。

编辑:正如其他人所指出的,可以省略对a的调用。 regUsers现在显式为IQueryable类型。

答案 1 :(得分:3)

写如下:

regUsers = regUsers.Where(s => s.User.LastName.Contains(searchString)).AsQueryable();

这将转换为您想要的结果!

更多详情:

What is the purpose of AsQueryable()?

修改

根据评论,更好的方法如下:

IQueryable<User> users = db.Users;

if (!String.IsNullOrEmpty(searchString))
{
    users = users.Where(s => s.User.LastName.Contains(searchString));
}

return View(users.ToList());

答案 2 :(得分:1)

作为替代方案,省略重复使用具有冲突类型的变量并将列表直接传递到View

[Authorize(Roles = "RegisteredUsers")]
public ActionResult Index(string searchString)
{   
    if (!String.IsNullOrEmpty(searchString))
    {
        return View(db.Users.Where(s => s.User.LastName.Contains(searchString)).ToList);
    }

    return View(new List<User>());
    //or if you want to return all users:
    return View(db.Users.ToList()); //you might want to consider `Skip` and `Take`
}

特别感谢@CodeCaster: 如果您的查询变得更复杂:

[Authorize(Roles = "RegisteredUsers")]
public ActionResult Index(string searchString)
{   
    IQueryable<User> query = db.Users;
    if (!String.IsNullOrEmpty(searchString))
    {
        query = query.Where(s => s.User.LastName.Contains(searchString));
    }

    //additional filtering can be applied to `query`

    return View(query.ToList());    
}

答案 3 :(得分:1)

错误很清楚。

您的代码中有两种不同的类型:

  • db.UsersDbSet<User>
  • regUsers.Where(s => s.User.LastName.Contains(searchString))IQueryable<User>

使用此声明:

var regUsers = db.Users;

您声明regUsers属于作业右侧的类型:DbSet<User>

您无法将Where()的结果分配给同一个变量,因为Where()的结果不是DbSet<User>

将变量明确声明为共同的祖先类型(IQueryable<User>,两种类型都实现):

IQueryable<Users> users = db.Users;

现在您可以将Where()的结果分配给同一个变量:

users = users.Where(s => s.User.LastName.Contains(searchString));

所以代码看起来像这样:

IQueryable<User> users = db.Users;

if (!String.IsNullOrEmpty(searchString))
{
    users = users.Where(s => s.User.LastName.Contains(searchString));
}

return View(users.ToList());