Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.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
Linq 为什么硬编码函数表达式会将查询速度提高四分钟?_Linq_Entity Framework_Objectset - Fatal编程技术网

Linq 为什么硬编码函数表达式会将查询速度提高四分钟?

Linq 为什么硬编码函数表达式会将查询速度提高四分钟?,linq,entity-framework,objectset,Linq,Entity Framework,Objectset,我将用作存储库类的父级。在父类EFRepository中,有一个方法调用传入Func方法的ObjectSet的Where子句。调用此代码并将其分配到我的网格后,此过程需要4分钟。但是,如果我硬编码对ObjectSet的调用,只需三秒。你知道为什么吗?看来编译器不知怎么搞砸了 private void button1_Click(object sender, RoutedEventArgs e) { IQueryable<

我将用作存储库类的父级。在父类EFRepository中,有一个方法调用传入Func方法的ObjectSet的Where子句。调用此代码并将其分配到我的网格后,此过程需要4分钟。但是,如果我硬编码对ObjectSet的调用,只需三秒。你知道为什么吗?看来编译器不知怎么搞砸了

private void button1_Click(object sender, RoutedEventArgs e)
    {                        
        IQueryable<PRODDATA> testP = test.Repository.Find(w => w.PCUST == 49 && w.PDTTK == 20101030); 

        DateTime firstDate = System.DateTime.Now;
//This is where it takes the most time when passing in the expression above. When the espression is hardcoded (see below) it speeds it up considerably.
        radGridView1.ItemsSource = testP;
        DateTime secondDate = System.DateTime.Now;                                   

    }

public class EFRepository<T> : IRepository<T> where T : PRODDATA
{
    public IUnitOfWork UnitOfWork { get; set; }
    private IObjectSet<T> _objectset;
    private IObjectSet<T> ObjectSet
    {
        get
        {
            if (_objectset == null)
            {
                _objectset = UnitOfWork.Context.CreateObjectSet<T>();
            }
            return _objectset;
        }
    }

    public virtual IQueryable<T> All()
    {
        return ObjectSet.AsQueryable();
    }

    public IQueryable<T> Find(Func<T, bool> expression)
    {
//Hardcoding this only takes 2 seconds.
        //return ObjectSet.Where(w => w.PCUST == 49 && w.PDTTK == 20101030).AsQueryable(); 

//passing expression takes 4 minutes.
        return ObjectSet.Where(expression).AsQueryable(); 
    }

    public void Add(T entity)
    {
        ObjectSet.AddObject(entity);
    }

    public void Delete(T entity)
    {
        ObjectSet.DeleteObject(entity);
    }

    public void Save()
    {
        UnitOfWork.Save();
    }
}
private void按钮1\u单击(对象发送者,路由目标)
{                        
IQueryable testP=test.Repository.Find(w=>w.PCUST==49&&w.PDTTK==20101030);
DateTime firstDate=System.DateTime.Now;
//这是在传递上面的表达式时花费最多时间的地方。当espression是硬编码的(见下文)时,它会大大加快速度。
radGridView1.ItemsSource=testP;
DateTime secondDate=System.DateTime.Now;
}
公共类eRepository:IRepository,其中T:PRODDATA
{
公共IUNITOWORK UNITOWORK{get;set;}
私有IObjectSet\u对象集;
私有IObjectSet对象集
{
得到
{
如果(_objectset==null)
{
_objectset=UnitOfWork.Context.CreateObjectSet();
}
返回对象集;
}
}
公共虚拟IQueryable All()
{
返回ObjectSet.AsQueryable();
}
公共IQueryable查找(函数表达式)
{
//硬编码这只需要2秒钟。
//返回ObjectSet.Where(w=>w.PCUST==49&&w.PDTTK==20101030).AsQueryable();
//传递表达式需要4分钟。
返回ObjectSet.Where(表达式).AsQueryable();
}
公共无效添加(T实体)
{
ObjectSet.AddObject(实体);
}
公共作废删除(T实体)
{
ObjectSet.DeleteObject(实体);
}
公共作废保存()
{
UnitOfWork.Save();
}
}

因为
Find
采用
Func
而不是
表达式。据推测,此查询被发送到DB引擎,因为它在
IQueryable
上运行。但是,如果表达式作为委托传递,而不是真正的表达式,那么LINQ到任何DB层都无法检查表达式并将其转换为SQL。这将导致整个数据集从db服务器发送到C#代码,然后在CLR中而不是db中应用“where”表达式

更改
Find
的签名

public IQueryable<T> Find(Func<T, bool> expression)
publicIQueryable查找(Func表达式)

publicIQueryable查找(表达式)

然后看看它的性能。

完美。你是个天才,谢谢你。我特别感谢你告诉我如何/为什么。
public IQueryable<T> Find(Expression<Func<T, bool>> expression)