【问题标题】:Subsonic 3 ActiveRecord Delete/Destroy throwing strange exceptionSubsonic 3 ActiveRecord Delete/Destroy 抛出奇怪的异常
【发布时间】:2010-01-26 18:46:29
【问题描述】:

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

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

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

Failed to convert parameter value from a Func`2 to a Int32.

堆栈跟踪如下:

System.InvalidOperationException 未处理 Message="无法将参数值从 Func`2 转换为 Int32。" 来源="SubSonic.Core" 堆栈跟踪: 在 SubSonic.Query.SqlQuery.Execute() 在 SubSonic.Repository.SubSonicRepository`1.Delete(对象键,IDataProvider 提供程序) 在 SubSonic.Repository.SubSonicRepository`1.Delete(对象键) 在 E:\temp\SS3TEst\SS3Test.DAL\ActiveRecord.cs:line 2149 中的 SS3Test.DAL.TestClass.Destroy(Func`2 表达式) 在 E:\temp\SS3TEst\SS3Test.Model\TestClass.cs:第 84 行中的 SS3Test.Model.TestClass.Delete(Int32warrantyId, Boolean destroy) 在 E:\temp\SS3TEst\SS3Test.GUI\FrmTestClass.cs:line 72 中的 SS3Test.GUI.FrmTestClass.btnDelete_Click(Object sender, EventArgs e) 在 System.Windows.Forms.Control.OnClick(EventArgs e) 在 System.Windows.Forms.Button.OnClick(EventArgs e) 在 System.Windows.Forms.Button.OnMouseUp(MouseEventArgs 事件) 在 System.Windows.Forms.Control.WmMouseUp(消息和 m,MouseButtons 按钮,Int32 点击) 在 System.Windows.Forms.Control.WndProc(消息和 m) 在 System.Windows.Forms.ButtonBase.WndProc(消息和 m) 在 System.Windows.Forms.Button.WndProc(消息和 m) 在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(消息& m) 在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(消息和 m) 在 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd,Int32 msg,IntPtr wparam,IntPtr lparam) 在 System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(味精和味精) 在 System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID,Int32 原因,Int32 pvLoopData) 在 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 原因,ApplicationContext 上下文) 在 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 原因,ApplicationContext 上下文) 在 System.Windows.Forms.Application.Run(窗体 mainForm) 在 E:\temp\SS3TEst\SS3Test.GUI\Program.cs:line 21 中的 SS3Test.GUI.Program.Main() 在 System.AppDomain._nExecuteAssembly(程序集程序集,字符串 [] 参数) 在 System.AppDomain.ExecuteAssembly(字符串 assemblyFile,证据 assemblySecurity,String [] args) 在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 在 System.Threading.ThreadHelper.ThreadStart_Context(对象状态) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback 回调,对象状态) 在 System.Threading.ThreadHelper.ThreadStart() 内部异常:System.InvalidCastException Message="无法将参数值从 Func`2 转换为 Int32。" 源="系统.数据" 堆栈跟踪: 在 System.Data.SqlClient.SqlParameter.CoerceValue(对象值,元类型destinationType) 在 System.Data.SqlClient.SqlParameter.GetCoercedValue() 在 System.Data.SqlClient.SqlParameter.Validate(Int32 索引,布尔 isCommandProc) 在 System.Data.SqlClient.SqlCommand.BuildParamList(TdsParser 解析器,SqlParameterCollection 参数) 在 System.Data.SqlClient.SqlCommand.BuildExecuteSql(CommandBehavior 行为,字符串 commandText,SqlParameterCollection 参数,_SqlRPC& rpc) 在 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior,RunBehavior runBehavior,布尔 returnStream,布尔异步) 在 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,RunBehavior runBehavior,布尔 returnStream,String 方法,DbAsyncResult 结果) 在 System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult 结果,字符串方法名,布尔值 sendToPipe) 在 System.Data.SqlClient.SqlCommand.ExecuteNonQuery() 在 SubSonic.DataProviders.DbDataProvider.ExecuteQuery(QueryCommand qry) 在 SubSonic.Query.SqlQuery.Execute() 内部异常:System.InvalidCastException Message="对象必须实现 IConvertible。" 来源="mscorlib" 堆栈跟踪: 在 System.Convert.ChangeType(对象值,类型转换类型,IFormatProvider 提供程序) 在 System.Data.SqlClient.SqlParameter.CoerceValue(对象值,元类型destinationType)

PS:- 我从这个答案中得到了一个解决方法,即从 db 中获取具有给定键的对象,然后对其调用 delete 。它有效,但我想知道为什么我会得到这个异常。我也在使用 SS 3.0.3(今天(26Jan2K10)下载)。

【问题讨论】:

    标签: c# activerecord subsonic subsonic3


    【解决方案1】:

    它看起来像一个正确的错误,因为 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

    【讨论】:

    • 看起来很有希望。我试试看。
    • 我在 GitHub 上的 Templates 项目中记录了一个问题。
    【解决方案2】:

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

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

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

    当然,这两个答案都取决于 Destroy 参数的实际预期。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-09
      相关资源
      最近更新 更多