背景
我使用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
答案 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)尝试通过在比较之前转换价值来确定价值,因此它适用于bit
和varchar
:
SqlFunctions.StringConvert((double)p.IsPropeller == "true"