Subsonic 3 ActiveRecord 删除/销毁抛出奇怪的异常

发布于 2024-08-19 09:48:34 字数 4828 浏览 3 评论 0原文

我有一个简单的表,其中包含主键(身份)和一些 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

或十年 2024-08-26 09:48:35

它看起来像是一个真正的错误,因为 ActiveRecord Destroy 方法所依赖的 SubSonicRepository 没有 Delete(expression) 重载。

我认为如果您进入 ActiveRecord.tt 模板文件并找到:

    public static void Destroy(Func<<#=tbl.ClassName#>, bool> expression) {
        var repo = GetRepo();
        repo.Delete(expression);
    }

并将 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:

    public static void Destroy(Func<<#=tbl.ClassName#>, bool> expression) {
        var repo = GetRepo();
        repo.Delete(expression);
    }

and replace Delete with DeleteMany that will delete all the records returning true for the given expression (hopefully just the one if you're using the primary key :)

GC

黑色毁心梦 2024-08-26 09:48:35

我不熟悉该库或函数,但错误消息暗示您正在将函数作为参数传递,其中需要 Int32。事实上,您正在将 lambda 函数(“==>”)作为参数传递给 Destroy。因此,首先要检查 Destroy 是否真的需要一个函数,或者一个 Integer。

如果不是这样,请注意 lambda 函数正在重新调整 bool(== 比较的结果),但该错误意味着需要 Int32。您可能必须将 bool 转换为 int,您可以使用 ?: 运算符轻松完成此操作,如下所示:

x => ((x.TestId == _testId) ? 1 : 0)

但是,当然,这两个答案都取决于 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:

x => ((x.TestId == _testId) ? 1 : 0)

But of course, both answers depend on what the Destroy parameter is actually expecting.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文