5

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

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

你调用的对象是空的。堆栈跟踪:
在 Microsoft.SharePoint.Linq.FieldRef.GetHashCode()
在 Microsoft.SharePoint.Linq.FieldRef.FieldRefEqualityComparer.GetHashCode(FieldRef obj)
在 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()
在 System.Linq.Buffer`1..ctor(IEnumerable`1 源) 在 System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 源) 在 Microsoft.SharePoint.Linq.SelectMappingInfo.GetDistinctMappedFields()
在 Microsoft.SharePoint.Linq.Rules.PushDownProcessor.SelectWithInfoOp.PushDownSelect(上下文 ctx)
在 Microsoft.SharePoint.Linq.Rules.PushDownProcessor.SelectWithInfoOp.Process(上下文 ctx)
在 Microsoft.SharePoint.Linq.Rules.GuardedRule`4.c__DisplayClass7.b__6(TSourceBase src,TContext ctx)
在 Microsoft.SharePoint.Linq.Rules.RewriteRule`2.Apply(TNode src, TContext ctx) 在 Microsoft.SharePoint.Linq.Rules.CacheRule`3.Apply(TSource src, TContext ctx)  
在 Microsoft.SharePoint.Linq.Rules.PushDownProcessor.b__0(表达式 e,上下文 ctx)
在 Microsoft.SharePoint.Linq.Rules.ChildRule`2.Apply(TNode src, TContext ctx) 在 Microsoft.SharePoint.Linq.Rules.PushDownProcessor.b__3(Expression e, Context ctx)
在 Microsoft.SharePoint.Linq.Rules.RewriteRule`2.Apply(TNode src, TContext ctx) 在 Microsoft.SharePoint.Linq.Rules.CacheRule`3.Apply(TSource src, TContext ctx)  
在 Microsoft.SharePoint.Linq.SPLinqProvider.Rewrite(表达式表达式,List`1& 假设)
在 Microsoft.SharePoint.Linq.SPLinqProvider.RewriteAndCompile[T](表达式表达式,List`1& 假设)
在 Microsoft.SharePoint.Linq.LinqQuery`1.GetEnumerator()
在 System.Collections.Generic.List`1..ctor(IEnumerable`1 集合)  
在 System.Linq.Enumerable.ToList[TSource](IEnumerable`1 源)  
在 Common.Configuration.ConfigurationRepository.GetConfiguration(String siteUrl) InnerException:

来源:Microsoft.SharePoint.Linq 目标站点: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()
    };
}

任何人都知道如何追踪导致此异常的原因?

2011 年 5 月 31 日更新:

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

我们看到在应用程序池被回收后发生了这种行为。修复此错误的唯一方法是执行完整的 IISreset。

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

希望有人能给我更多关于这个例外的信息吗?

4

3 回答 3

2

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

于 2012-01-02T13:59:34.530 回答
1

在我们的项目中,我们大量使用 Linq to 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);
        }
    }
}

在我们的案例中,我们还让 catch 代码向我们发送了一封电子邮件,以便我们知道问题已经发生并且修复工作有效。

于 2014-03-31T13:58:49.613 回答
0

我们遇到了同样的事情。以下步骤解决了它:

  • 通过服务器上的 SPMetal 重新生成 dataContext 类导致问题
  • 将类重新应用到您的项目并重建
  • 重新部署解决方案(将 DLL 复制到 GAC 工作)
于 2011-05-25T05:07:09.743 回答