【问题标题】:ObjectSet's Where() method and memoryObjectSet 的 Where() 方法和内存
【发布时间】:2013-02-08 15:07:38
【问题描述】:

我正在使用 ObjectSet 的方法在表中进行各种查询,即从中选择一些记录:

    var results = Repository.Find(c => c.Enabled == 1).ToList();

这是我的存储库的 Find 方法:

    public IEnumerable<T> Find(Func<T, bool> predicate)
    {
        try
        {
            return _objectSet.Where<T>(predicate);
        }
        catch
        {
            throw;
        }
    }

现在,如果目标表中有大约 1,000,000 条记录,我可以看到进程的内存使用量增长了很多,即使我正在执行的 Find 调用应该最多返回几条记录.

似乎所有的记录都被拉到客户端,然后被过滤。这显然不是我想要 LINQ 做的。

你觉得我在做什么明显有问题吗?

提前致谢。

【问题讨论】:

  • 不要使用 IEnumerable 它会将每个数据行一次拉入内存,而不是您应该使用 IQueryable
  • 您的Find 方法根本没有任何成效。为什么不直接在Repository 上使用Where
  • @MUG4N 他只是将它用于他的输出,应该已经被过滤了,所以这不是问题。

标签: c# database memory-management entity-framework-4 objectset


【解决方案1】:

我认为你应该使用Expression&lt;Func&lt;T, bool&gt;&gt; 而不是普通的Func&lt;T, bool&gt;

public IEnumerable<T> Find(Expression<Func<T, bool>> predicate) {
  // your code
}

Where 被重载(参见ObjectSet Class),Func&lt;T&gt;-overload 由IEnumerable&lt;T&gt; 定义,而Expression&lt;TDelegate&gt;IQueryable&lt;T&gt; 使用。因为predicateFunc&lt;T&gt;,所以编译器会调用为IEnumerable&lt;T&gt; 定义的扩展方法,进而获取所有记录并对对象执行LINQ。

【讨论】:

  • Expression 来自哪个命名空间? System.Linq.Expressions ?
  • 那我一定是做错了,因为我明白了:非泛型类型 'System.Linq.Expressions.Expression' 不能与类型参数一起使用 使用泛型类型 'System.Linq.Expressions .Expression' 需要 1 个类型参数
  • 我明白了。对不起,我错了。基本上它是Expression&lt;Func&lt;T, bool&gt;&gt; 而不是Expression&lt;T, bool&gt;。我编辑了我的答案,我会仔细检查。
  • 对,我通过谷歌找到了另一个有效的例子。谢谢。
  • 现在应该是对的,不是吗?我仔细检查了我的 Visual Studio 2012 安装。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多