Lambda按参数性能排序

时间:2014-05-10 13:33:21

标签: c# lambda entity-framework-6

我遇到了无法解决的性能问题。如果您查看下面的代码,它可以正常工作,但是当我更改OrderByDescending(x => x.ID)以便它使用参数sortOrder时,它会给我一个超时。

我使用OrderByDescending中提供的相同lambda表达式调用该函数。

m_DAL.GetPastes(page, userName, x => x.ID).ToList<Paste>();

这有效但我希望能够将sortOrder作为参数传递。

    public IEnumerable<Paste> GetPastes(int page, string username, Func<Paste, object> sortOrder)
    {
        return this.Filter<Paste>(x => x.Expires == null || x.Expires > DateTime.UtcNow)
            .Where(x => x.AccessMode.Key == 1 || (x.AccessMode.Key == 2 && x.User.UserName == username))
            .Where(x => x.CaptchaOK == true || (x.AccessMode.Key == 2 && x.User.UserName == username))
            .OrderByDescending(x => x.ID)
            .Skip(m_pagesize * page)
            .Take(m_pagesize)
            .ToList<Paste>();
    }

这让我暂停:

public IEnumerable<Paste> GetPastes(int page, string username, Func<Paste, object> sortOrder)
    {
        return this.Filter<Paste>(x => x.Expires == null || x.Expires > DateTime.UtcNow)
            .Where(x => x.AccessMode.Key == 1 || (x.AccessMode.Key == 2 && x.User.UserName == username))
            .Where(x => x.CaptchaOK == true || (x.AccessMode.Key == 2 && x.User.UserName == username))
            .OrderByDescending(sortOrder)
            .Skip(m_pagesize * page)
            .Take(m_pagesize)
            .ToList<Paste>();
    }

如何解决此问题?这个函数的定义是错误的吗?

1 个答案:

答案 0 :(得分:4)

如果你只使用Func<Paste, object> - 你会得到OrderBy的重载,它会检索所有内存并命令它们。为了获得更高的性能,我建议您使用Expression<T>,它将在SQL中翻译并在数据库端运行:

编辑: 此外,您可以使您的方法通用,省略这一点:

  

NotSupportedException:无法将类型“System.Int32”强制转换为类型   'System.Object的'。 LINQ to Entities仅支持转换EDM原语   或枚举类型。

public IEnumerable<Paste> GetPastes<TOrderKey>(int page, string username, 
                   Expression<Func<Paste, TOrderKey>> sortOrder)
{
    // code from the question
}

请注意,由于类型推断,您调用此方法的方式不会更改:

m_DAL.GetPastes(page, userName, x => x.ID).ToList<Paste>();