Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 对象的LINQ分页_C#_.net_Linq_Paging - Fatal编程技术网

C# 对象的LINQ分页

C# 对象的LINQ分页,c#,.net,linq,paging,C#,.net,Linq,Paging,如何在LINQ查询中实现分页? 实际上,就目前而言,如果可以模仿SQLtop函数,我会感到满意。但是,我确信,对完全分页支持的需求迟早会出现 var queryResult = from o in objects where ... select new { A = o.a, B =

如何在LINQ查询中实现分页? 实际上,就目前而言,如果可以模仿SQLtop函数,我会感到满意。但是,我确信,对完全分页支持的需求迟早会出现

var queryResult = from o in objects
                  where ...
                  select new
                      {
                         A = o.a,
                         B = o.b
                      }
                   ????????? TOP 10????????

您正在寻找
Skip
Take
扩展方法<代码>跳过移动经过结果中的前N个元素,返回剩余元素
Take
返回结果中的前N个元素,删除所有剩余元素

有关如何使用这些方法的更多信息,请参见MSDN:

假设您已经考虑到页码应该从0开始(按照注释中的建议每1减少一次),您可以这样做:

int numberOfObjectsPerPage = 10;
var queryResultPage = queryResult
  .Skip(numberOfObjectsPerPage * pageNumber)
  .Take(numberOfObjectsPerPage);
否则,如果页码基于1(如@Alvin所建议)

编辑-已删除跳过(0),因为它不是必需的

var queryResult = (from o in objects where ...
                      select new
                      {
                          A = o.a,
                          B = o.b
                      }
                  ).Take(10);

使用
Skip
Take
绝对是一种方法。如果我实现了这一点,我可能会编写自己的扩展方法来处理分页(以使代码更具可读性)。当然,实现可以使用
跳过
采取

static class PagingUtils {
  public static IEnumerable<T> Page<T>(this IEnumerable<T> en, int pageSize, int page) {
    return en.Skip(page * pageSize).Take(pageSize);
  }
  public static IQueryable<T> Page<T>(this IQueryable<T> en, int pageSize, int page) {
    return en.Skip(page * pageSize).Take(pageSize);
  }
}

不知道这是否对任何人都有帮助,但我发现它对我的目的很有用:

private static IEnumerable<T> PagedIterator<T>(IEnumerable<T> objectList, int PageSize)
{
    var page = 0;
    var recordCount = objectList.Count();
    var pageCount = (int)((recordCount + PageSize)/PageSize);

    if (recordCount < 1)
    {
        yield break;
    }

    while (page < pageCount)
    {
        var pageData = objectList.Skip(PageSize*page).Take(PageSize).ToList();

        foreach (var rd in pageData)
        {
            yield return rd;
        }
        page++;
    }
}

因此,这将迭代每个作者,每次获取100个作者。

以下是我使用LINQ对对象进行分页时的性能方法:

public static IEnumerable<IEnumerable<T>> Page<T>(this IEnumerable<T> source, int pageSize)
{
    Contract.Requires(source != null);
    Contract.Requires(pageSize > 0);
    Contract.Ensures(Contract.Result<IEnumerable<IEnumerable<T>>>() != null);

    using (var enumerator = source.GetEnumerator())
    {
        while (enumerator.MoveNext())
        {
            var currentPage = new List<T>(pageSize)
            {
                enumerator.Current
            };

            while (currentPage.Count < pageSize && enumerator.MoveNext())
            {
                currentPage.Add(enumerator.Current);
            }
            yield return new ReadOnlyCollection<T>(currentPage);
        }
    }
}

如果您对多个页面感兴趣,那么这些垃圾
跳过
获取
将是非常低效的。

我使用这种扩展方法:

public static IQueryable<T> Page<T, TResult>(this IQueryable<T> obj, int page, int pageSize, System.Linq.Expressions.Expression<Func<T, TResult>> keySelector, bool asc, out int rowsCount)
{
    rowsCount = obj.Count();
    int innerRows = rowsCount - (page * pageSize);
    if (innerRows < 0)
    {
        innerRows = 0;
    }
    if (asc)
        return obj.OrderByDescending(keySelector).Take(innerRows).OrderBy(keySelector).Take(pageSize).AsQueryable();
    else
        return obj.OrderBy(keySelector).Take(innerRows).OrderByDescending(keySelector).Take(pageSize).AsQueryable();
}

public IEnumerable<Data> GetAll(int RowIndex, int PageSize, string SortExpression)
{
    int totalRows;
    int pageIndex = RowIndex / PageSize;

    List<Data> data= new List<Data>();
    IEnumerable<Data> dataPage;

    bool asc = !SortExpression.Contains("DESC");
    switch (SortExpression.Split(' ')[0])
    {
        case "ColumnName":
            dataPage = DataContext.Data.Page(pageIndex, PageSize, p => p.ColumnName, asc, out totalRows);
            break;
        default:
            dataPage = DataContext.vwClientDetails1s.Page(pageIndex, PageSize, p => p.IdColumn, asc, out totalRows);
            break;
    }

    foreach (var d in dataPage)
    {
        clients.Add(d);
    }

    return data;
}
public int CountAll()
{
    return DataContext.Data.Count();
}
公共静态IQueryable页面(此IQueryable对象,int页面,int页面大小,System.Linq.Expressions.Expression键选择器,bool asc,out int rowsunt)
{
rowsCount=obj.Count();
int innerRows=ROWSCONT-(页面*页面大小);
如果(内部行<0)
{
innerRows=0;
}
如果(asc)
返回obj.OrderByDescending(keySelector).Take(innerRows).OrderBy(keySelector).Take(pageSize).AsQueryable();
其他的
返回obj.OrderBy(keySelector).Take(innerRows).OrderByDescending(keySelector).Take(pageSize).AsQueryable();
}
公共IEnumerable GetAll(int-RowIndex、int-PageSize、string-SortExpression)
{
整数行;
int pageIndex=行索引/页面大小;
列表数据=新列表();
IEnumerable数据页;
bool asc=!SortExpression.Contains(“DESC”);
开关(SortExpression.Split(“”)[0])
{
案例“ColumnName”:
dataPage=DataContext.Data.Page(pageIndex、PageSize、p=>p.ColumnName、asc、OutTotalRows);
打破
违约:
dataPage=DataContext.vwClientDetails1s.Page(pageIndex,PageSize,p=>p.IdColumn,asc,out totalRows);
打破
}
foreach(数据页中的变量d)
{
添加(d);
}
返回数据;
}
公共整数CountAll()
{
返回DataContext.Data.Count();
}
Batchsize显然是一个整数。这充分利用了整数只需删除小数位数这一事实

我半开玩笑的回答,但它会做你想做的,因为它是延迟的,如果你这样做,你不会招致很大的性能损失

pages.First(p => p.Key == thePage)
此解决方案不适用于LinqToEntities,我甚至不知道它是否能将此转化为一个好的查询。

公共LightDataTable页面选择(int pageNumber,int setsPerPage,Func prection=null)
    public LightDataTable PagerSelection(int pageNumber, int setsPerPage, Func<LightDataRow, bool> prection = null)
    {
        this.setsPerPage = setsPerPage;
        this.pageNumber = pageNumber > 0 ? pageNumber - 1 : pageNumber;
        if (!ValidatePagerByPageNumber(pageNumber))
            return this;

        var rowList = rows.Cast<LightDataRow>();
        if (prection != null)
            rowList = rows.Where(prection).ToList();

        if (!rowList.Any())
            return new LightDataTable() { TablePrimaryKey = this.tablePrimaryKey };
        //if (rowList.Count() < (pageNumber * setsPerPage))
        //    return new LightDataTable(new LightDataRowCollection(rowList)) { TablePrimaryKey = this.tablePrimaryKey };

        return new LightDataTable(new LightDataRowCollection(rowList.Skip(this.pageNumber * setsPerPage).Take(setsPerPage).ToList())) { TablePrimaryKey = this.tablePrimaryKey };
  }
{ this.setsPerPage=setsPerPage; this.pageNumber=pageNumber>0?pageNumber-1:pageNumber; 如果(!ValidatePagerByPageNumber(pageNumber)) 归还这个; var rowList=rows.Cast(); if(prection!=null) rowList=行。其中(prection).ToList(); 如果(!rowList.Any()) 返回新的LightDataTable(){TablePrimaryKey=this.TablePrimaryKey}; //if(rowList.Count()<(页码*设置每页)) //返回新的LightDataTable(新的LightDataRowCollection(rowList)){TablePrimaryKey=this.TablePrimaryKey}; 返回新的LightDataTable(新的LightDataRowCollection(rowList.Skip(this.pageNumber*SetPerPage).Take(SetPerPage.ToList()){TablePrimaryKey=this.TablePrimaryKey}; }
这就是我所做的。 通常从1开始,但在IList中从0开始。 所以,如果您有152行,这意味着您有8个分页,但在IList中,您只有7个分页。 这会让你明白的

var results=(medicineInfo.OrderBy(x=>x.id)
.跳过((第1页)*2页)

.采取(2)项措施有两个主要选项:

.NET>=4.0 :

  • 使用System.Linq.Dynamic添加;在顶端
  • 用法:
    var people=people.AsQueryable().OrderBy(“Make ASC,Year DESC”).ToList()
  • 你也可以买它

    .NET<4.0 :

    私有静态只读哈希表访问器=新哈希表();
    私有静态只读哈希表callSites=new Hashtable();
    私有静态CallSite GetCallSiteLocked(字符串名称){
    var callSite=(callSite)callSites[name];
    if(callSite==null)
    {
    callSites[name]=callSite=callSite.Create(
    Binder.GetMember(CSharpBinderFlags.None、name、typeof(AccessorCache),
    新建CSharpArgumentInfo[]{CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None,null)});
    }
    返回呼叫站点;
    }
    内部静态Func GetAccessor(字符串名称)
    {
    Func访问器=(Func)访问器[名称];
    if(访问器==null)
    {
    锁(存取器)
    {
    访问器=(Func)访问器[名称];
    if(访问器==null)
    {
    如果(name.IndexOf('.')>=0){
    string[]props=name.Split('.');
    CallSite[]arr=Array.ConvertAll(props,GetCallSiteLocked);
    访问者=目标=>
    {
    对象val=(对象)目标;
    对于(int i=0;ipublic static IEnumerable<IEnumerable<T>> Page<T>(this IEnumerable<T> source, int pageSize)
    {
        Contract.Requires(source != null);
        Contract.Requires(pageSize > 0);
        Contract.Ensures(Contract.Result<IEnumerable<IEnumerable<T>>>() != null);
    
        using (var enumerator = source.GetEnumerator())
        {
            while (enumerator.MoveNext())
            {
                var currentPage = new List<T>(pageSize)
                {
                    enumerator.Current
                };
    
                while (currentPage.Count < pageSize && enumerator.MoveNext())
                {
                    currentPage.Add(enumerator.Current);
                }
                yield return new ReadOnlyCollection<T>(currentPage);
            }
        }
    }
    
    var items = Enumerable.Range(0, 12);
    
    foreach(var page in items.Page(3))
    {
        // Do something with each page
        foreach(var item in page)
        {
            // Do something with the item in the current page       
        }
    }
    
    public static IQueryable<T> Page<T, TResult>(this IQueryable<T> obj, int page, int pageSize, System.Linq.Expressions.Expression<Func<T, TResult>> keySelector, bool asc, out int rowsCount)
    {
        rowsCount = obj.Count();
        int innerRows = rowsCount - (page * pageSize);
        if (innerRows < 0)
        {
            innerRows = 0;
        }
        if (asc)
            return obj.OrderByDescending(keySelector).Take(innerRows).OrderBy(keySelector).Take(pageSize).AsQueryable();
        else
            return obj.OrderBy(keySelector).Take(innerRows).OrderByDescending(keySelector).Take(pageSize).AsQueryable();
    }
    
    public IEnumerable<Data> GetAll(int RowIndex, int PageSize, string SortExpression)
    {
        int totalRows;
        int pageIndex = RowIndex / PageSize;
    
        List<Data> data= new List<Data>();
        IEnumerable<Data> dataPage;
    
        bool asc = !SortExpression.Contains("DESC");
        switch (SortExpression.Split(' ')[0])
        {
            case "ColumnName":
                dataPage = DataContext.Data.Page(pageIndex, PageSize, p => p.ColumnName, asc, out totalRows);
                break;
            default:
                dataPage = DataContext.vwClientDetails1s.Page(pageIndex, PageSize, p => p.IdColumn, asc, out totalRows);
                break;
        }
    
        foreach (var d in dataPage)
        {
            clients.Add(d);
        }
    
        return data;
    }
    public int CountAll()
    {
        return DataContext.Data.Count();
    }
    
    var pages = items.Select((item, index) => new { item, Page = index / batchSize }).GroupBy(g => g.Page);
    
    pages.First(p => p.Key == thePage)
    
        public LightDataTable PagerSelection(int pageNumber, int setsPerPage, Func<LightDataRow, bool> prection = null)
        {
            this.setsPerPage = setsPerPage;
            this.pageNumber = pageNumber > 0 ? pageNumber - 1 : pageNumber;
            if (!ValidatePagerByPageNumber(pageNumber))
                return this;
    
            var rowList = rows.Cast<LightDataRow>();
            if (prection != null)
                rowList = rows.Where(prection).ToList();
    
            if (!rowList.Any())
                return new LightDataTable() { TablePrimaryKey = this.tablePrimaryKey };
            //if (rowList.Count() < (pageNumber * setsPerPage))
            //    return new LightDataTable(new LightDataRowCollection(rowList)) { TablePrimaryKey = this.tablePrimaryKey };
    
            return new LightDataTable(new LightDataRowCollection(rowList.Skip(this.pageNumber * setsPerPage).Take(setsPerPage).ToList())) { TablePrimaryKey = this.tablePrimaryKey };
      }
    
    private static readonly Hashtable accessors = new Hashtable();
    
    private static readonly Hashtable callSites = new Hashtable();
    
    private static CallSite<Func<CallSite, object, object>> GetCallSiteLocked(string name) {
        var callSite = (CallSite<Func<CallSite, object, object>>)callSites[name];
        if(callSite == null)
        {
            callSites[name] = callSite = CallSite<Func<CallSite, object, object>>.Create(
                        Binder.GetMember(CSharpBinderFlags.None, name, typeof(AccessorCache),
                    new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }));
        }
        return callSite;
    }
    
    internal static Func<dynamic,object> GetAccessor(string name)
    {
        Func<dynamic, object> accessor = (Func<dynamic, object>)accessors[name];
        if (accessor == null)
        {
            lock (accessors )
            {
                accessor = (Func<dynamic, object>)accessors[name];
                if (accessor == null)
                {
                    if(name.IndexOf('.') >= 0) {
                        string[] props = name.Split('.');
                        CallSite<Func<CallSite, object, object>>[] arr = Array.ConvertAll(props, GetCallSiteLocked);
                        accessor = target =>
                        {
                            object val = (object)target;
                            for (int i = 0; i < arr.Length; i++)
                            {
                                var cs = arr[i];
                                val = cs.Target(cs, val);
                            }
                            return val;
                        };
                    } else {
                        var callSite = GetCallSiteLocked(name);
                        accessor = target =>
                        {
                            return callSite.Target(callSite, (object)target);
                        };
                    }
                    accessors[name] = accessor;
                }
            }
        }
        return accessor;
    }
    public static IOrderedEnumerable<dynamic> OrderBy(this IEnumerable<dynamic> source, string property)
    {
        return Enumerable.OrderBy<dynamic, object>(source, AccessorCache.GetAccessor(property), Comparer<object>.Default);
    }
    public static IOrderedEnumerable<dynamic> OrderByDescending(this IEnumerable<dynamic> source, string property)
    {
        return Enumerable.OrderByDescending<dynamic, object>(source, AccessorCache.GetAccessor(property), Comparer<object>.Default);
    }
    public static IOrderedEnumerable<dynamic> ThenBy(this IOrderedEnumerable<dynamic> source, string property)
    {
        return Enumerable.ThenBy<dynamic, object>(source, AccessorCache.GetAccessor(property), Comparer<object>.Default);
    }
    public static IOrderedEnumerable<dynamic> ThenByDescending(this IOrderedEnumerable<dynamic> source, string property)
    {
        return Enumerable.ThenByDescending<dynamic, object>(source, AccessorCache.GetAccessor(property), Comparer<object>.Default);
    }
    
       public static IEnumerable<IEnumerable<T>> PageIterator<T>(this IQueryable<T> source, int pageSize)
                {
                    Contract.Requires(source != null);
                    Contract.Requires(pageSize > 0);
                    Contract.Ensures(Contract.Result<IEnumerable<IQueryable<T>>>() != null);
    
                    using (var enumerator = source.GetEnumerator())
                    {
                        while (enumerator.MoveNext())
                        {
                            var currentPage = new List<T>(pageSize)
                            {
                                enumerator.Current
                            };
    
                            while (currentPage.Count < pageSize && enumerator.MoveNext())
                            {
                                currentPage.Add(enumerator.Current);
                            }
                            yield return new ReadOnlyCollection<T>(currentPage);
                        }
                    }
                }