【问题标题】:Get LINQ to preload a complete table获取 LINQ 以预加载完整的表
【发布时间】:2009-11-10 12:40:01
【问题描述】:

我需要 LINQ 来抓取整个表格,但这似乎不起作用......每次我通过 pkey 选择值时,都会再次触发一个选择......

所以,实际上这段代码:

        DataContext dc = new DataContext();

        dc.Stores.ToList();

        Store st = dc.Stores.SingleOrDefault(p => p.Id == 124671);

正在制作一个

select * from store 

在“ToList()”方法和一个附加的

select * from store where id = 124671

在它下面的选择部分...

当然,我想阻止它进行第二次选择..

我会怎么做? (我不想将 ToList() 结果存储在 List 之类的附加属性中)

更新:

关于你的回答,这意味着:

Store st = stores.SingleOrDefault(p => p.Id == 124671);
Store st = stores.SingleOrDefault(p => p.Id == 124671);

会触发对 DB 的 2 次选择,这会使 LINQ-idea 无用吗?!或者我在这里做错了什么?

我认为 LINQ 基本上会保存我在选择中抓取的所有数据,并且只有在“缓存”中找不到数据时才执行另一个请求。所以,我认为它就像某种“神奇”存储层之间我的应用程序和数据库..

更新 #2

只是你明白了......我想在开始时失去性能(当抓取所有数据时)并在我从“缓存”数据中选择时赢回改变......

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    试试这个:

    DataContext dc = new DataContext();
    
    var allStores = dc.Stores.ToList();
    
    Store st = allStores.SingleOrDefault(p => p.Id == 124671);
    

    【讨论】:

    • 一个不错的简单方法。喜欢它;-p
    【解决方案2】:

    (我假设它知道 id 是主键等)

    哪个确切版本?这看起来像 LINQ-to-SQL;在 3.5(无服务包)中,是的 - 身份管理器是 bit rubbish at this。它得到了better in 3.5 SP1,应该是fixed in 4.0

    在 .NET 3.5 SP1 中,Single(predicate) 方法适用于 IIRC,所以也许使用它并捕获块? try/catch 将比网络跃点快。

    来自后面的连接帖子:

    此错误现已修复,并将 包含在 .NET Framework 4.0 中。这 优化先搜索缓存 现在将完成基于 ID 的查找 为了 Single/SingleOrDefault/First/FirstOrDefault(谓词) 也 Where(predicate).Single/SingleOrDefault/First/FirstOrDefault(), 谓词具有相同的地方 限制和以前一样。

    【讨论】:

      【解决方案3】:

      您正在做的是将结果作为列表,将其丢弃,然后再次查询原始结果。这就是为什么您需要两次访问数据库的原因。

      ToList 方法返回列表作为结果,您可以将其存储在变量中并从以下位置查询:

      var stores = dc.Stores.ToList();
      
      Store st = stores.SingleOrDefault(p => p.Id == 124671);
      

      【讨论】:

        【解决方案4】:

        简短的回答 - 你不需要 ToList()

        长答案 - 在提供的示例中,您的 ToList() 调用完全是多余的。使用 Linq 时,在您实际枚举 IQueryable 之前,它不会在您的数据库服务器上实际执行任何操作。

        如果你只是想通过 PK 得到一条记录,那么只需要直接使用数据上下文:

        var theStore = dc.Stores.SingleOrDefault(p => p.Id == 124671);
        

        如果您真的想获取所有记录并对其进行迭代,您可以在表上调用 ToList():

        var allStores = dc.Stores.ToList()
        

        如果你想要的只是一条记录,执行

        var allStores = dc.Stores.ToList();
        Store st = allStores.SingleOrDefault(p => p.Id == 124671);
        

        完全失败。您将所有结果放入内存,然后让 .Net 过滤列表,从而失去数据库等索引的所有好处。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-12-15
          相关资源
          最近更新 更多