Linq to SharePoint抛出空引用异常

时间:2011-03-24 14:48:06

标签: linq sharepoint-2010 linq-to-sharepoint

在我们的SharePoint 2010项目中,我们使用Linq to SharePoint获取ConfigurationItems列表。在我们的测试环境中,我们从未从此列表中获取数据时遇到问题。在我们的生产环境中,我们现在有时(我们现在找不到模式)在循环遍历列表中的项时获得空引用异常。

以下是从Linq到SharePoint代码抛出的异常:

Object reference not set to an instance of an object. StackTrace: 
at Microsoft.SharePoint.Linq.FieldRef.GetHashCode()
at Microsoft.SharePoint.Linq.FieldRef.FieldRefEqualityComparer.GetHashCode(FieldRef obj)
at System.Linq.Set`1.InternalGetHashCode(TElement value)  at System.Linq.Set`1.Find(TElement value, Boolean add)  at System.Linq.Enumerable.d__7a`1.MoveNext()
at System.Linq.Buffer`1..ctor(IEnumerable`1 source)  at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)  at Microsoft.SharePoint.Linq.SelectMappingInfo.GetDistinctMappedFields()
at Microsoft.SharePoint.Linq.Rules.PushDownProcessor.SelectWithInfoOp.PushDownSelect(Context ctx)
at Microsoft.SharePoint.Linq.Rules.PushDownProcessor.SelectWithInfoOp.Process(Context ctx)
at Microsoft.SharePoint.Linq.Rules.GuardedRule`4.c__DisplayClass7.b__6(TSourceBase src, TContext ctx)
at Microsoft.SharePoint.Linq.Rules.RewriteRule`2.Apply(TNode src, TContext ctx)  at Microsoft.SharePoint.Linq.Rules.CacheRule`3.Apply(TSource src, TContext ctx)  
at Microsoft.SharePoint.Linq.Rules.PushDownProcessor.b__0(Expression e, Context ctx)
at Microsoft.SharePoint.Linq.Rules.ChildRule`2.Apply(TNode src, TContext ctx)  at Microsoft.SharePoint.Linq.Rules.PushDownProcessor.b__3(Expression e, Context ctx)
at Microsoft.SharePoint.Linq.Rules.RewriteRule`2.Apply(TNode src, TContext ctx)  at Microsoft.SharePoint.Linq.Rules.CacheRule`3.Apply(TSource src, TContext ctx)  
at Microsoft.SharePoint.Linq.SPLinqProvider.Rewrite(Expression expression, List`1& assumptions)
at Microsoft.SharePoint.Linq.SPLinqProvider.RewriteAndCompile[T](Expression expression, List`1& assumptions)
at Microsoft.SharePoint.Linq.LinqQuery`1.GetEnumerator()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)  
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)  
at Common.Configuration.ConfigurationRepository.GetConfiguration(String siteUrl) InnerException:

Source: Microsoft.SharePoint.Linq TargetSite: Int32 GetHashCode()

这里是我们在GetConfiguration方法中使用的代码。

using (SpDataContext dataContext = new SpDataContext(siteUrl))
{
    result = new ConfigurationModel()
    {
        Configurations = (from item in dataContext.GasportConfiguration
                          select new ConfigurationItem()
                          {
                              Key = item.Key,
                              Value = item.Value,
                              Environment = (Environment)Enum.Parse(typeof(Environment), item.Environment.ToString(), true)
                          }).ToList()
    };
}

任何人都有关于如何跟踪导致此异常的原因的想法?

更新31-05-2011:

我们找到了一种模式,通过这种模式我们可以在生产环境中重现这种行为。而且在我们的测试环境中,我们也遇到了这个问题,我们使用AdPlus从中提取了一些Crash Dump文件。

我们发现在回收应用程序池后会发生此行为。解决此错误的唯一方法是执行完整的IISreset。

在crashdump分析中,我发现了一条异常消息,指出: 例外代码:0xC0000005 异常信息:线程尝试读取或写入其没有适当访问权限的虚拟地址。

希望有人能就这个例外提供更多信息吗?

3 个答案:

答案 0 :(得分:2)

不幸的是,我们还没有找到解决此问题的方案,并决定从LINQ迁移到SharePoint。对于一些列表,我们将其更改为SQL表(Linq to SQL),对于SharePoint列表,我们将其更改回CAML。

答案 1 :(得分:1)

在我们的项目中,我们大量使用Linq来分享Sharepoint并且间歇性地出现这个问题,并且仅在生产时出现。当它发生时似乎唯一可行的是IISReset。

我们更深入地研究这个问题,但仍然不知道是什么导致它发生。但是我们发现你可以通过清除一些私有缓存变量来自动修复它。这是我们的代码:

public static class SharePointless
{
    public static void Reset()
    {
        var assembly = Assembly.GetAssembly(typeof(EntityList<>));
        var providerType = assembly.GetType("Microsoft.SharePoint.Linq.SPLinqProvider");
        var singleton = providerType.GetField("Singleton", BindingFlags.Static | BindingFlags.Public);
        if (singleton == null) throw new Exception("Expected field doesn't exist in SPLinqProvider");
        singleton.SetValue(null, Activator.CreateInstance(providerType));

        var itemMappingInfoType = assembly.GetType("Microsoft.SharePoint.Linq.SPItemMappingInfo");
        var cachedMappings = itemMappingInfoType.GetField("cachedMappings", BindingFlags.Static | BindingFlags.NonPublic);
        if (cachedMappings == null) throw new Exception("Expected field doesn't exist in SPItemMappingInfo");
        cachedMappings.SetValue(null, null);
    }
}

使用示例:

public static void MyMethod(bool retry)
{
    try
    {
        using (var db = new MyDataContext())
        {
            DoStuff(db);
        }
    }
    catch (NullReferenceException ex)
    {
        if (retry && ex.StackTrace.Contains("FieldRef.GetHashCode"))
        {
            SharePointless.Reset();
            MyMethod(false);
        }
    }
}

在我们的案例中,我们也有捕获代码向我们发送电子邮件,因此我们知道问题已经发生并且修复工作正常。

答案 2 :(得分:0)

我们遇到了同样的事情。以下步骤解决了这个问题:

  • 通过服务器上的SPMetal重新生成dataContext类导致问题
  • 将课程重新应用于您的项目并重建
  • 重新部署解决方案(将DLL复制到GAC工作)