使用Entity Framework获取包含特定记录的分页结果

时间:2017-09-28 00:31:40

标签: c# asp.net sql-server entity-framework pagination

我正在处理一个管理视图,该视图列出了ASP.NET身份用户以及创建新用户的链接。现在,该链接只会将您带到一个新页面,其中包含用于创建新用户的表单。保存新用户后,它会将您发送回用户列表页面。列表页面已经接受了pageNumber和pageSize参数(其中pageSize是要一次检索和显示的用户数。)我想要做的是显示包含刚创建的用户的页面,但是如何确定哪个页面那个用户落在哪?

我需要知道所有用户集中该用户的索引,但我不想检索所有用户来执行此操作。有没有办法让Entity Framework基本上返回Row_Number()。我的具体记录?否则我觉得我只需要创建一个存储过程给我索引,但我可以使用代码优先的身份数据库(我是代码优先和身份的新手。)

编辑: 请求的代码摘录(为简洁起见而修改):

public ActionResult Users(int? pageNum, int? pageSize)
{
    ActionResult response;

    AccountAdminUsersVM vm = new AccountAdminUsersVM();
    vm.PageSize = pageSize ?? 50;
    vm.CurrentPage = pageNum ?? 1;

    try
    {
        int totalCount;
        vm.UsersPage = GetUsers(vm.CurrentPage, vm.PageSize, out totalCount);
        vm.TotalCount = totalCount;

        ...

        response = View(vm);
    }
    catch (Exception ex)
    {
        ...
    }

    return response;
}

private List<ApplicationUser> GetUsers(int page, int pageSize, out int totalCount)
{
    totalCount = UserManager.Users.Count();
    return UserManager.Users
            .OrderBy(u => u.UserName)
            .Skip((page - 1) * pageSize)
            .Take(pageSize)
            .ToList();
}

private ApplicationUserManager UserManager
{
    get
    {
        return HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
    }
}

这就是我想象的SQL需要看起来的样子(除了按列的顺序也需要参数化):

SELECT  t1.RowNum
FROM    (
            SELECT Id, ROW_NUMBER() OVER(ORDER BY UserName) AS RowNum
            FROM    AspNetUsers
        ) t1
WHERE t1.Id = @Id

这对Linq来说似乎是一个很高的命令。

1 个答案:

答案 0 :(得分:1)

当您调用context.SaveChanges()/ await AsyncSaveChanges()时,结果包含新创建的实体。您可以将其传回您的重定向操作。

编辑:需要调用ToList()。所以它不会是延迟加载,如果预计有很多应用程序用户,那么这不会是一个推荐的选项。

//this is how you can get the index of the user in an ordered list. "_newUserName" is being passed in, either as a User object or string (your call)

var index = UserManager.Users.OrderBy(a=>a.UserName).ToList().Select((user, index) => new {user,index}).Where(a=>a.user.UserName == "_newUserName").Select(a=>a.index).FirstOrDefault();

//then determine the page new user sits on
var page = (index / pageSize ) + 1;
return UserManager.Users
        .OrderBy(u => u.UserName)
        .Skip((page - 1) * pageSize)
        .Take(pageSize)
        .ToList();