代码之家  ›  专栏  ›  技术社区  ›  TheVillageIdiot

亚音速3活动记录删除/销毁引发异常

  •  2
  • TheVillageIdiot  · 技术社区  · 15 年前

    我有一个简单的表,其中有一个主键(标识)和几个 varchar 类型列。我尝试使用以下语法删除/销毁具有给定主键的记录:

    SS3Test.DAL.TestClass.Destroy(x => x.TestId == _testId);

    但当它被调用时,我会得到以下异常:

    Failed to convert parameter value from a Func ` 2 to a 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:-我有一个解决方法,从这个答案中,即从db中获取具有给定键的对象,然后对它调用delete。它起作用了,但我想知道为什么我会得到这个例外。另外,我使用的是SS 3.0.3(今天下载(2010年1月26日))。

    2 回复  |  直到 15 年前
        1
  •  1
  •   GC.    15 年前

    它看起来像一个适当的bug,因为ActiveRecord销毁方法所依赖的子sonicRepository没有 Delete(expression) 超载。

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

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

    并更换 Delete 具有 DeleteMany 这将删除为给定表达式返回“真”的所有记录(如果使用主键,希望只有一个记录)。

    气相色谱

        2
  •  1
  •   Andy Jacobs    15 年前

    我不熟悉库或函数,但错误消息意味着您正在传递一个函数作为参数,其中需要一个int32。实际上,您正在传递lambda函数(“=>”)作为要销毁的参数。所以首先要检查的是destroy是否真的想要一个函数,或者一个整数。

    如果不是这样,请注意lambda函数正在重新调整bool(一个==比较的结果),但错误意味着需要一个int32。你可能需要把你的bool转换成int,你可以很容易地使用它?:这样的操作员:

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

    当然,这两个答案都取决于销毁参数的实际期望值。