【问题标题】:Workaround for LINQ to SQL Entity Identity Caching and Compiled Query Bug?LINQ to SQL 实体身份缓存和编译查询错误的解决方法?
【发布时间】:2009-09-15 14:42:35
【问题描述】:

我在 linq to sql 中遇到了一个错误,在该错误中,在编译查询中执行主键查询时,身份缓存不起作用。

我编写了以下示例来演示身份缓存的用法。它仅在第一次命中时执行一次对数据库的调用,之后每次都从数据上下文的缓存中检索客户实体。

    for(int i=0; i<10; i++)
    {
        DataContext.GetTable<Customer>().Single(c=>c.Id == 1);
    }

不幸的是,当我将上述示例转换为编译查询时,它无法利用身份缓存,实际上对数据库执行了 10 次调用。

    for(int i=0; i<10; i++)
    {
        RetrieveCustomer(DataContext, 1);
    }

    private static readonly Func<DataContext, int, Customer> RetrieveCustomer =
    CompiledQuery.Compile((DataContext context, int id) => context.GetTable<Customer>().Single(c=>c.Id == id));

有没有其他人遇到过这个问题并为此创建了解决方法?基于服务器的应用程序利用编译查询和身份缓存非常重要,所以我希望这是其他人以前解决过的问题!

【问题讨论】:

    标签: linq-to-sql caching identity compiled


    【解决方案1】:

    看起来像一个错误 - 这个区域有一个数字。

    作为一种变通方法,我不会为这样一个小/简单的操作创建编译查询 - 编译查询的真正好处是对于需要大量时间处理成 TSQL 的大型查询。

    更新:这是一个错误,已解决,不会修复。

    【讨论】:

    • 编译这么小的查询似乎很愚蠢,但我们的应用程序是一个接受许多客户端请求的服务器,并且每个请求必须进行数百甚至数千次数据库检索,所以每一位真的很重要。
    • 在这种情况下,您可能想要测量它 - 如果解析此查询的开销比编译的查询路由更有效,我会感到惊讶。
    【解决方案2】:

    我最终使用了一种肮脏的技巧来解决这个问题,方法是使用反射调用一个名为 GetCachedEntity 的 linq 实体对象的私有方法来强制利用缓存。我没有时间实现更简洁的解决方案,但对于任何对此主题感兴趣的人,我建议您为此场景实现自己的缓存机制。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-06
      • 1970-01-01
      相关资源
      最近更新 更多