C# Lambda按参数排序的性能

C# Lambda按参数排序的性能,c#,lambda,entity-framework-6,C#,Lambda,Entity Framework 6,我有一个无法解决的性能问题。如果您查看下面的代码,它可以正常工作,但是当我更改OrderByDescending(x=>x.ID)时,它使用paramatersortOrder来代替,它会给我一个超时 我用我在OrderByDescending中提供的lambda表达式调用函数 m_DAL.GetPastes(page, userName, x => x.ID).ToList<Paste>(); m_DAL.GetPastes(页面,用户名,x=>x.ID).ToList()

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

我用我在
OrderByDescending
中提供的lambda表达式调用函数

m_DAL.GetPastes(page, userName, x => x.ID).ToList<Paste>();
m_DAL.GetPastes(页面,用户名,x=>x.ID).ToList();
这是可行的,但我希望能够将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 GetPastes(整型页面、字符串用户名、函数排序器)
{
返回此.Filter(x=>x.Expires==null | | x.Expires>DateTime.UtcNow)
。其中(x=>x.AccessMode.Key==1 | |(x.AccessMode.Key==2&&x.User.UserName==UserName))
。其中(x=>x.CaptchaOK==true | |(x.AccessMode.Key==2&&x.User.UserName==UserName))
.OrderByDescending(x=>x.ID)
.跳过(m_pagesize*页)
.Take(m_页面大小)
.ToList();
}
这给了我一个超时时间:

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>();
    }
public IEnumerable GetPastes(整型页面、字符串用户名、函数排序器)
{
返回此.Filter(x=>x.Expires==null | | x.Expires>DateTime.UtcNow)
。其中(x=>x.AccessMode.Key==1 | |(x.AccessMode.Key==2&&x.User.UserName==UserName))
。其中(x=>x.CaptchaOK==true | |(x.AccessMode.Key==2&&x.User.UserName==UserName))
.OrderByDescending(排序器)
.跳过(m_pagesize*页)
.Take(m_页面大小)
.ToList();
}

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

如果您只使用
Func
-您会得到超负荷的
OrderBy
,它将所有实体检索到内存中并对它们进行排序。为了获得更高的性能,我建议您使用
Expression
,它将转换为SQL并在db端运行:

编辑: 此外,您还可以使您的方法具有通用性,以忽略以下内容:

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

public IEnumerable GetPastes(int页,字符串用户名,
表达式(排序器)
{
//问题代码
}
请注意,调用此方法的方式不会因为类型推断而改变:

m_DAL.GetPastes(page, userName, x => x.ID).ToList<Paste>();
m_DAL.GetPastes(页面,用户名,x=>x.ID).ToList();

如果您只使用
Func
-您会得到超负荷的
OrderBy
,它将所有实体检索到内存中并对它们进行排序。为了获得更高的性能,我建议您使用
Expression
,它将转换为SQL并在db端运行:

编辑: 此外,您还可以使您的方法具有通用性,以忽略以下内容:

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

public IEnumerable GetPastes(int页,字符串用户名,
表达式(排序器)
{
//问题代码
}
请注意,调用此方法的方式不会因为类型推断而改变:

m_DAL.GetPastes(page, userName, x => x.ID).ToList<Paste>();
m_DAL.GetPastes(页面,用户名,x=>x.ID).ToList();

确切地说,虽然您可以从表达式转换为func,但事实并非如此,linq to iqueryables(任何数据库提供程序)可以在表达式上生成sql,如果您传递一个func,您将向下链接到对象,这意味着您将从数据库中检索所有行,然后将其中的每一行都放入orderby。因此,如果您的页面大小为20,并且您的表包含200万行,则第一个示例从数据库中检索到应用程序的20行,第二个示例检索到200万行,这是完全正常的,速度要慢得多。这几乎奏效了。=)它解决了性能问题,但我必须将object更改为int,否则我会收到一个错误“附加信息:无法将类型“System.Int32”转换为类型“System.object”。LINQ to Entities仅支持转换EDM基元或枚举类型。“您能用通用版本更新示例吗?”?对象对我来说似乎不起作用。确切地说,虽然可以从表达式转换为func,但事实并非如此,linq to iqueryables(任何数据库提供程序)对表达式进行处理以生成sql,如果传递func,则要向下链接到对象,这意味着要从数据库检索所有行,然后把他们每个人都放到订单上。因此,如果您的页面大小为20,并且您的表包含200万行,则第一个示例从数据库中检索到应用程序的20行,第二个示例检索到200万行,这是完全正常的,速度要慢得多。这几乎奏效了。=)它解决了性能问题,但我必须将object更改为int,否则我会收到一个错误“附加信息:无法将类型“System.Int32”转换为类型“System.object”。LINQ to Entities仅支持转换EDM基元或枚举类型。“您能用通用版本更新示例吗?”?这个物体似乎对我不起作用。