Subsonic 3 ActiveRecord 删除/销毁抛出奇怪的异常
我有一个简单的表,其中包含主键(身份)和一些 varchar
类型列。我尝试使用以下语法删除/销毁具有给定主键的记录:
SS3Test.DAL.TestClass.Destroy(x => x.TestId == _testId);
但当调用它时,我得到以下异常:
无法将参数值从 Func
`2 转换为 Int32。
堆栈跟踪如下:
System.InvalidOperationException was unhandled Message="Failed to convert parameter value from a Func`2 to a Int32." Source="SubSonic.Core" StackTrace: at SubSonic.Query.SqlQuery.Execute() at SubSonic.Repository.SubSonicRepository`1.Delete(Object key, IDataProvider provider) at SubSonic.Repository.SubSonicRepository`1.Delete(Object key) at SS3Test.DAL.TestClass.Destroy(Func`2 expression) in E:\temp\SS3TEst\SS3Test.DAL\ActiveRecord.cs:line 2149 at SS3Test.Model.TestClass.Delete(Int32 warrantyId, Boolean destroy) in E:\temp\SS3TEst\SS3Test.Model\TestClass.cs:line 84 at SS3Test.GUI.FrmTestClass.btnDelete_Click(Object sender, EventArgs e) in E:\temp\SS3TEst\SS3Test.GUI\FrmTestClass.cs:line 72 at System.Windows.Forms.Control.OnClick(EventArgs e) at System.Windows.Forms.Button.OnClick(EventArgs e) at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent) at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.ButtonBase.WndProc(Message& m) at System.Windows.Forms.Button.WndProc(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData) at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) at System.Windows.Forms.Application.Run(Form mainForm) at SS3Test.GUI.Program.Main() in E:\temp\SS3TEst\SS3Test.GUI\Program.cs:line 21 at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args) at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() InnerException: System.InvalidCastException Message="Failed to convert parameter value from a Func`2 to a Int32." Source="System.Data" StackTrace: at System.Data.SqlClient.SqlParameter.CoerceValue(Object value, MetaType destinationType) at System.Data.SqlClient.SqlParameter.GetCoercedValue() at System.Data.SqlClient.SqlParameter.Validate(Int32 index, Boolean isCommandProc) at System.Data.SqlClient.SqlCommand.BuildParamList(TdsParser parser, SqlParameterCollection parameters) at System.Data.SqlClient.SqlCommand.BuildExecuteSql(CommandBehavior behavior, String commandText, SqlParameterCollection parameters, _SqlRPC& rpc) at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe) at System.Data.SqlClient.SqlCommand.ExecuteNonQuery() at SubSonic.DataProviders.DbDataProvider.ExecuteQuery(QueryCommand qry) at SubSonic.Query.SqlQuery.Execute() InnerException: System.InvalidCastException Message="Object must implement IConvertible." Source="mscorlib" StackTrace: at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) at System.Data.SqlClient.SqlParameter.CoerceValue(Object value, MetaType destinationType)
PS:- 我从这个答案中得到了解决方法,即从数据库中获取具有给定键的对象,然后对其调用删除。它有效,但我想知道为什么我会收到此异常。我还使用 SS 3.0.3(今天下载(2010 年 1 月 26 日))。
I've a simple table with a primary key (Identity) and few varchar
type columns. I try to delete/destroy a record with given primary key using following syntax:
SS3Test.DAL.TestClass.Destroy(x => x.TestId == _testId);
but when it is called I get following Exception:
Failed to convert parameter value from a Func
`2 to a Int32.
The stack trace is as follow:
System.InvalidOperationException was unhandled Message="Failed to convert parameter value from a Func`2 to a Int32." Source="SubSonic.Core" StackTrace: at SubSonic.Query.SqlQuery.Execute() at SubSonic.Repository.SubSonicRepository`1.Delete(Object key, IDataProvider provider) at SubSonic.Repository.SubSonicRepository`1.Delete(Object key) at SS3Test.DAL.TestClass.Destroy(Func`2 expression) in E:\temp\SS3TEst\SS3Test.DAL\ActiveRecord.cs:line 2149 at SS3Test.Model.TestClass.Delete(Int32 warrantyId, Boolean destroy) in E:\temp\SS3TEst\SS3Test.Model\TestClass.cs:line 84 at SS3Test.GUI.FrmTestClass.btnDelete_Click(Object sender, EventArgs e) in E:\temp\SS3TEst\SS3Test.GUI\FrmTestClass.cs:line 72 at System.Windows.Forms.Control.OnClick(EventArgs e) at System.Windows.Forms.Button.OnClick(EventArgs e) at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent) at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.ButtonBase.WndProc(Message& m) at System.Windows.Forms.Button.WndProc(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData) at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) at System.Windows.Forms.Application.Run(Form mainForm) at SS3Test.GUI.Program.Main() in E:\temp\SS3TEst\SS3Test.GUI\Program.cs:line 21 at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args) at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() InnerException: System.InvalidCastException Message="Failed to convert parameter value from a Func`2 to a Int32." Source="System.Data" StackTrace: at System.Data.SqlClient.SqlParameter.CoerceValue(Object value, MetaType destinationType) at System.Data.SqlClient.SqlParameter.GetCoercedValue() at System.Data.SqlClient.SqlParameter.Validate(Int32 index, Boolean isCommandProc) at System.Data.SqlClient.SqlCommand.BuildParamList(TdsParser parser, SqlParameterCollection parameters) at System.Data.SqlClient.SqlCommand.BuildExecuteSql(CommandBehavior behavior, String commandText, SqlParameterCollection parameters, _SqlRPC& rpc) at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe) at System.Data.SqlClient.SqlCommand.ExecuteNonQuery() at SubSonic.DataProviders.DbDataProvider.ExecuteQuery(QueryCommand qry) at SubSonic.Query.SqlQuery.Execute() InnerException: System.InvalidCastException Message="Object must implement IConvertible." Source="mscorlib" StackTrace: at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) at System.Data.SqlClient.SqlParameter.CoerceValue(Object value, MetaType destinationType)
PS:- I've got a workaround from this answer, namely to get the object with given key from db and then calling delete on it. It works but I want to know why I'm getting this exception. Also I'm using SS 3.0.3 (downloaded today (26Jan2K10)).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
它看起来像是一个真正的错误,因为 ActiveRecord Destroy 方法所依赖的 SubSonicRepository 没有
Delete(expression)
重载。我认为如果您进入 ActiveRecord.tt 模板文件并找到:
并将
Delete
替换为DeleteMany
,这将删除给定表达式返回 true 的所有记录(希望只是如果您使用主键,则为一个:)GC
it looks like a proper bug, as the SubSonicRepository on which the ActiveRecord Destroy method depends doesn't have a
Delete(expression)
overload.I think if you go into your ActiveRecord.tt template file and find:
and replace
Delete
withDeleteMany
that will delete all the records returning true for the given expression (hopefully just the one if you're using the primary key :)GC
我不熟悉该库或函数,但错误消息暗示您正在将函数作为参数传递,其中需要 Int32。事实上,您正在将 lambda 函数(“==>”)作为参数传递给 Destroy。因此,首先要检查 Destroy 是否真的需要一个函数,或者一个 Integer。
如果不是这样,请注意 lambda 函数正在重新调整 bool(== 比较的结果),但该错误意味着需要 Int32。您可能必须将 bool 转换为 int,您可以使用 ?: 运算符轻松完成此操作,如下所示:
但是,当然,这两个答案都取决于 Destroy 参数实际期望的内容。
I'm not familiar with the library or function, but the error message implies that you are passing a function as a parameter where an Int32 is expected. And in fact you are passing a lambda function (the "=>") as the parameter to Destroy. So the first thing to check is if Destroy really wants a function, or an Integer.
If that's not it, note that the lambda function is retuning a bool (the result of a == comparison), but the error implies that an Int32 is wanted. You might have to convert your bool to int, which you could easily do with the ?: operator like this:
But of course, both answers depend on what the Destroy parameter is actually expecting.