Linq to SharePoint выбрасывает исключение нулевой ссылки

В нашем проекте SharePoint 2010 мы используем Linq to SharePoint, чтобы получить список ConfigurationItems. В наших средах тестирования у нас никогда не было проблем с получением данных из этого списка. В нашей производственной среде мы теперь иногда (мы не можем найти шаблон прямо сейчас) получаем исключение нулевой ссылки при циклическом просмотре элементов в списке.

Ниже приведено исключение из кода Linq to SharePoint:

В экземпляре объекта не задана ссылка на объект. StackTrace: в Microsoft.SharePoint.Linq.FieldRef.GetHashCode() в Microsoft.SharePoint.Linq.FieldRef.FieldRefEqualityComparer.GetHashCode(FieldRef obj) в System.Linq.Set`1.InternalGetHashCode(значение элемента TEL) в System.Lement. `1.Find(значение TElement, логическое добавление) в 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(Context ctx) в Microsoft.SushDL.L.SelectWithInfoOp.Process(Context ctx) в Microsoft.SharePoint.Linq.Rules.GuardedRule`4.c__DisplayClass7.b__6(TSourceBase src, TContext ctx) в Microsoft.SharePoint.Linq.Rules.RewriteRule`2.Apply, TNT) в 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(выражение 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.SPLinP.Rewrite(Выражение выражения, List`1& предположения) в Microsoft.SharePoint.Linq.SPLinqProvider.RewriteAndCompile[T](Выражение выражения, List`1& предположения) в Microsoft.SharePoint.Linq.LinqQuery`1.GetEnumerator() в системе.Collections.Generic.List`1..ctor(коллекция IEnumerable`1) в System.Linq.Enumerable.ToList[TSource](источник IEnumerable`1) в Common.Configuration.ConfigurationRepository.GetConfiguration(String siteUrl) InnerException: Источник: 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:

Мы нашли образец, каким образом мы можем воспроизвести это поведение в нашей производственной среде. А также в нашей тестовой среде у нас тоже была эта проблема, из которой мы извлекли некоторые файлы Crash Dump с помощью AdPlus.

Мы видим, что такое поведение происходит после повторного использования пула приложений. Единственный способ исправить эту ошибку - выполнить полный сброс IIS.

В анализе сбоя я обнаружил сообщение об исключении, которое гласит: Код исключения: 0xC0000005 Информация об исключении: Поток пытается прочитать или записать виртуальный адрес, к которому у него нет соответствующего доступа.

Надеюсь, что кто-то может дать мне больше информации об этом исключении?

3 ответа

Решение

К сожалению, мы не нашли решения этой проблемы и решили перейти от LINQ к SharePoint. Для нескольких списков мы изменили его на таблицы SQL (Linq to SQL), а для списков SharePoint мы вернулись к CAML.

В нашем проекте мы активно используем 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);
        }
    }
}

В нашем случае мы также получили код пересылки, отправив нам электронное письмо, чтобы мы знали, что проблема возникла и исправление сработало.

Мы столкнулись с тем же. Следующие шаги решили это:

  • Восстановление класса dataContext через SPMetal на сервере, вызывающее проблему
  • Повторно примените класс к своему проекту и пересоберите
  • Повторно разверните решение (копирование DLL в GAC сработало)
Другие вопросы по тегам