3

我使用Dane Morgridge 的存储库代码作为我的存储库类的父级。在父类 EFRepository 中,有一个方法调用 ObjectSet 的 Where 子句并传入 Func 方法。调用此代码并将其分配给我的网格后,该过程需要 4 分钟。但是,如果我对 ObjectSet 的 Where 的调用进行硬编码,则只需三秒钟。任何想法为什么?似乎编译器以某种方式搞砸了。

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();
    }
}
4

1 回答 1

3

因为Find需要 aFunc<T,bool>而不是Expression<Func<T,bool>>. 据推测,这个查询被发送到一个数据库引擎,因为它在一个IQueryable<T>. 但是,如果表达式作为委托而不是真正的表达式传递,则 LINQ-to-whatever-DB 层无法检查表达式并将其转换为 SQL。这导致整个数据集从 db 服务器发送到 C# 代码,然后在 CLR 中而不是在 DB 中应用“where”表达式。

更改Findfrom的签名

public IQueryable<T> Find(Func<T, bool> expression)

public IQueryable<T> Find(Expression<Func<T, bool>> expression)

然后看看它的表现如何。

于 2010-11-17T17:05:38.813 回答