DataContext使用.NET 4编译查询问题

时间:2010-10-11 07:51:42

标签: linq-to-sql .net-4.0 datacontext linq.compiledquery

我的项目(UI层是asp.mvc)是使用.NET 3.5开发的。升级到.NET 4.0后,我遇到了编译查询的问题:

 [ArgumentException: Query was compiled for a different mapping source than the one associated with the specified DataContext.]
   System.Data.Linq.CompiledQuery.ExecuteQuery(DataContext context, Object[] args) +863348
   System.Data.Linq.CompiledQuery.Invoke(TArg0 arg0, TArg1 arg1) +110

每当我运行查询时,我都会传递我的上下文

return StaticQueries.getTopFiveOrders(mContext, int howMany);


public static Func<Mycontext, int, IQueryable<Order>> getTopFiveOrders
            = CompiledQuery.Compile
                ((Mycontext mContext, int howMany) =>
                 ( some query).Distinct());

第二个请求发生错误。

3 个答案:

答案 0 :(得分:4)

这是由于编译查询的运行方式发生了变化。

他们现在需要始终使用相同的上下文运行。

This Microsoft connect page解释了为何进行了更改:

  

这种情况下的问题是由于CompiledQuery需要将相同的映射源用于所有执行。在用于重现问题的代码示例中,每次使用新映射源的DataContext的不同实例,但查询无法报告此问题,并且只是默默地失败。如果您使用DataContext.Log属性或其他日志记录(如SQL Server Profiler),您将看到第二个UPDATE甚至没有发送到服务器。

     

这已在.NET Framework 4.0中得到修复,因此报告的异常将包含“查询是为与指定的DataContext关联的映射源编译的不同映射源”之类的消息,并且它不仅仅是默默地失败。但是,您提供的代码正常工作是正确的方法,因为它对LinqTestDataContext的所有实例使用相同的静态映射源。

基本上它始终是一个问题,但过去常常无声地失败,它们只是在.NET 4中明确失败。

答案 1 :(得分:2)

我花了很多时间来研究这个以及.NET 4.0中的行为是如何被改变的。我在博客中更详细地详述了我的发现:

http://www.roushtech.net/2014/01/19/statically-compiled-linq-queries-broken-in-net-4-0/

粗略的是:微软做了一些改变,以保护人们不要做一些愚蠢的事情(在不同的映射之间重用编译的查询),但似乎已经打破了主要的性能优势(在SAME的不同上下文之间重用编译的查询) MAPPING,但不同的映射实例。)

使用getter或作为类成员的CompiledQuery只会导致不断的重新编译,并且没有真正的性能优势。

答案 2 :(得分:0)

我也面临类似的问题。我从编译的查询中删除了静态,它工作正常。虽然我还没有发现它在性能方面有多大差异。