日期:2014-05-20  浏览次数:20771 次

LINQ中将Func<TEntry,T>作为方法参数传递将导致效率急剧降低?.
工作中用到Linq,在大量数据分页时遇到一个奇怪的问题:将Func<TEntry,T>作为方法参数传递将导致无法读取数据。

请看如下代码:
C# code

protected void Page_Load(object sender, EventArgs e)
{
    long recordCount, pageCount;
    var paged = GetData(30, p,x=>true, x => x.id, out recordCount, out pageCount);
    d1 = DateTime.Now;
    list.DataSource = paged;
    list.DataBind();
    Response.Write("计时:" + (DateTime.Now - d1).TotalMilliseconds + "ms<br />");
}
private IQueryable<kaoqin_bak> GetData(
    int _pageSize, int _pageIndex, 
    Func<kaoqin_bak,bool> where,
    Func<kaoqin_bak, int> order, 
    out long _recordCount, out long _pageCount)
{
    KaoQinDataContext db = new KaoQinDataContext();
    var paged = (from x in db.kaoqin_bak select x)
    .Where(where)
    .OrderByDescending(order)
    .Skip((_pageIndex - 1) * _pageSize)
    .Take(_pageSize).AsQueryable();

    _recordCount = (from p in db.kaoqin_bak select p.id).LongCount();
    _pageCount = _recordCount / _pageSize;

    return paged;
}



按正常来讲,以上代码没有问题,但几乎没办法打开页面,IIS进程占用内存和CPU直线上升。

但是我讲Func<TEntry,T>参数去掉,硬编码到方法体内就能正常打开页面,百万计数据只需要20毫秒就可以打开:
C# code

……
var paged = GetData(30, p, out recordCount, out pageCount);
……
private IQueryable<kaoqin_bak> GetData(
    int _pageSize, int _pageIndex, 
    out long _recordCount, out long _pageCount)
{
    KaoQinDataContext db = new KaoQinDataContext();
    var paged = (from x in db.kaoqin_bak select x)
    .Where(x=>true)
    .OrderByDescending(x=>x.id)
    .Skip((_pageIndex - 1) * _pageSize)
    .Take(_pageSize).AsQueryable();

    _recordCount = (from p in db.kaoqin_bak select p.id).LongCount();
    _pageCount = _recordCount / _pageSize;

    return paged;
}


请问这是怎么回事呢?

------解决方案--------------------
用Expression<Func<TEntry,T>>而不是Func<TEntry,T>
------解决方案--------------------
当你使用Linq to SQL的时候,可以设置DataContext的.Log = Console.Out,看看你的代码到底是怎么跟数据库交互的。