我有一个简单的表,其中包含主键(Identity)和少量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(今天下载(26Jan2K10))。
答案 0 :(得分:1)
我不熟悉库或函数,但错误消息暗示您将函数作为参数传递,其中需要Int32。事实上,您将lambda函数(“=>”)作为参数传递给Destroy。所以要检查的第一件事是Destroy是否真的想要一个函数或整数。
如果不是这样,请注意lambda函数重新调整bool(==比较的结果),但错误意味着需要Int32。您可能必须将bool转换为int,您可以使用?:运算符轻松地将其转换为:
x => ((x.TestId == _testId) ? 1 : 0)
但当然,两个答案都取决于Destroy参数实际期望的内容。
答案 1 :(得分: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