Linq to SharePoint throwing null reference exception
In our SharePoint 2010 project we are using Linq to SharePoint to get a list of ConfigurationItems. On our testing environments we never had issues fetching data from this list. On our production environment we are now sometimes (we cannot find a pattern right now) getting a null reference exception when looping through the items in the list.
Below is the exception whe are getting thrown from the Linq to SharePoint code:
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()
And here the code we use in our GetConfiguration开发者_开发技巧 method.
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()
};
}
Anyone having ideas on how to track this down to what's causing this exception?
UPDATE 31-05-2011:
We found a pattern in which way we can reproduce this behaviour on our production environment. And also on our test environment we had this issue too, from which we extracted some Crash Dump files by using AdPlus.
We see this behaviour occuring after the application pool is recycled. The only way to fix this error is to perform a full IISreset.
In the crashdump analysis I found an exception message that states: Exception Code: 0xC0000005 Exception Information: The thread tries to read from or write to a virtual address for which it does not have the appropriate access.
Hope that someone could give me some more information on this exception?
Unfortunately we haven't found a solution for this issue and decided to move away from LINQ to SharePoint. For a few lists we have changed it to SQL tables (Linq to SQL) and for the SharePoint Lists we moved back to CAML.
In our project we use Linq to Sharepoint heavily and were having this problem come up intermittently, and only on production. The only thing that seemed to work when it happened was an IISReset.
We dug into the problem a little deeper and still don't know what causes it to happen. But we found that you can automatically fix it when it occurs by clearing some private cache variables. Here's our code:
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);
}
}
Example usage:
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);
}
}
}
In our case we also had the catch code send us an email so we knew that the problem happened and the fix worked.
We came across the same thing. The following steps solved it:
- Regeneration of the dataContext class via SPMetal on the server causing the problem
- Reapply the class to your project and rebuild
- Redeploy the solution (copying the DLL to the GAC worked)
精彩评论