ienumberable.Any()和.Count()抛出TargetInvocationException,即使我检查是否为null

时间:2015-08-10 20:55:55

标签: c# linq linq-to-sql

背景

我使用LINQ to SQL从数据库中获取信息。我最近更改了查询以使用数据库的更新版本,我将字符串列切换到位列。但是,当我查看旧版本的数据库时,它会崩溃。

我希望程序以空列表打开,而不是崩溃,这样用户可以更改设置,以便下次在正确的位置查找。如果在打开时崩溃,则无法更改设置。

代码:

LINQ查询运行正常,但是如果我尝试使用.Any().Count()检查它是否为空,或者我尝试将其作为列表投放,它会崩溃并告诉我TargetInvocationException,内部异常为NullReferenceException。但是,它不是空的。

IEnumerable<Airplane> propPlanes = _dataContext.Airplanes.Where(p =>
    p != null &&
    p.IsPropeller == true // used to be p.IsPropeller == "YES" 
);

List<Airplane> propPlanesList = new List<Airplane>();

if (propPlanes != null && _dataContext.Airplanes != null)  // expression is always true
{
    if (propPlanes.Any())                     // throws TargetInvocationException 
    {
        propPlanesList = propPlanes.ToList(); // would throwTargetInvocationException
    }
}

return propPlanesList ;

如何检查查询中是否有任何内容?

TargetInvocationException的堆栈跟踪

   at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
   at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
   at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
   at System.Activator.CreateInstance(Type type, Boolean nonPublic)
   at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, StackCrawlMark& stackMark)
   at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
   at System.Activator.CreateInstance(Type type, Object[] args)
   at System.Xaml.Schema.SafeReflectionInvoker.CreateInstanceCritical(Type type, Object[] arguments)
   at System.Xaml.Schema.XamlTypeInvoker.CreateInstance(Object[] arguments)
   at MS.Internal.Xaml.Runtime.ClrObjectRuntime.CreateInstance(XamlType xamlType, Object[] args)
   at System.Xaml.XamlObjectWriter.Logic_CreateAndAssignToParentStart(ObjectWriterContext ctx)
   at System.Xaml.XamlObjectWriter.WriteStartMember(XamlMember property)
   at System.Windows.Markup.WpfXamlLoader.TransformNodes(XamlReader xamlReader, XamlObjectWriter xamlWriter, Boolean onlyLoadOneNode, Boolean skipJournaledProperties, Boolean shouldPassLineNumberInfo, IXamlLineInfo xamlLineInfo, IXamlLineInfoConsumer xamlLineInfoConsumer, XamlContextStack`1 stack, IStyleConnector styleConnector)
   at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
   at System.Windows.Markup.WpfXamlLoader.LoadBaml(XamlReader xamlReader, Boolean skipJournaledProperties, Object rootObject, XamlAccessLevel accessLevel, Uri baseUri)
   at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream)
   at System.Windows.Application.LoadBamlStreamWithSyncInfo(Stream stream, ParserContext pc)
   at System.Windows.Application.LoadComponent(Uri resourceLocator, Boolean bSkipJournaledProperties)
   at System.Windows.Application.DoStartup()
   at System.Windows.Application.<.ctor>b__1(Object unused)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.DispatcherOperation.InvokeImpl()
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.ProcessQueue()
   at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Application.RunInternal(Window window)
   at System.Windows.Application.Run()
   at ClaytonSystem.App.Main() in \\pcppnasw02\users$\cclayto\My Documents\Work\GitHub\c\V2\WPFDataGrid\obj\Debug\App.g.cs:line 0
   at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
   at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext, String[] activationCustomData)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone()
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

InnerException的堆栈跟踪(NullReferenceException)

   at System.Data.Linq.SqlClient.QueryConverter.VisitInvocation(InvocationExpression invoke)
   at System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node)
   at System.Data.Linq.SqlClient.QueryConverter.VisitExpression(Expression exp)
   at System.Data.Linq.SqlClient.QueryConverter.VisitBinary(BinaryExpression b)
   at System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node)
   at System.Data.Linq.SqlClient.QueryConverter.VisitExpression(Expression exp)
   at System.Data.Linq.SqlClient.QueryConverter.VisitBinary(BinaryExpression b)
   at System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node)
   at System.Data.Linq.SqlClient.QueryConverter.VisitExpression(Expression exp)
   at System.Data.Linq.SqlClient.QueryConverter.VisitBinary(BinaryExpression b)
   at System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node)
   at System.Data.Linq.SqlClient.QueryConverter.Visit(Expression node)
   at System.Data.Linq.SqlClient.QueryConverter.VisitWhere(Expression sequence, LambdaExpression predicate)
   at System.Data.Linq.SqlClient.QueryConverter.VisitSequenceOperatorCall(MethodCallExpression mc)
   at System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node)
   at System.Data.Linq.SqlClient.QueryConverter.ConvertOuter(Expression node)
   at System.Data.Linq.SqlClient.SqlProvider.BuildQuery(Expression query, SqlNodeAnnotations annotations)
   at System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query)
   at System.Data.Linq.DataQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
   at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source)
   at ClaytonSystem.MainWindow.GetCheckTasks() in \\pcppnasw02\users$\cclayto\My Documents\Work\GitHub\c\V2\WPFDataGrid\Window1.xaml.cs:line 611
   at ClaytonSystem.MainWindow.ListCheckTasks() in \\pcppnasw02\users$\cclayto\My Documents\Work\GitHub\c\V2\WPFDataGrid\Window1.xaml.cs:line 751
   at ClaytonSystem.MainWindow..ctor() in \\pcppnasw02\users$\cclayto\My Documents\Work\GitHub\c\V2\WPFDataGrid\Window1.xaml.cs:line 129

1 个答案:

答案 0 :(得分:0)

我怀疑这个问题是由于您在模型中将string引用类型更改为bool值类型并且数据库尚未更新的事实引起的。 Linq-To-Sql期望IsPropeller属性始终具有其值并且在无法将检索到的“是”/“否”string转换为bool时会爆炸。

当Linq-To-Sql尝试创建您的实体实例时,似乎发生错误。

虽然我不知道这个问题的真实答案,因为您使用的Linq-To-Sql并非如预期的那样,您可以尝试以下方法:

1)删除p != null检查,因为这不能直接转换为SQL,可能会导致读取所有数据记录并在客户端进行过滤;

2)在IsPropeller属性上添加额外的空值检查以欺骗Linq-To-Sql执行null检查:

p.IsPropeller != null && p.IsPropeller == true

3)如果这没有帮助,请将IsPropeller类型更改为bool?并添加额外的null支票:

p.IsPropeller.HasValue && p.IsPropeller == true

4)尝试通过在比较之前转换价值来确定价值,因此它适用于bitvarchar

SqlFunctions.StringConvert((double)p.IsPropeller == "true"