2010-01-26 3 views
2

У меня простая таблица с первичным ключом (Identity) и несколькими столбцами типа varchar. Я пытаюсь удалить/уничтожить запись с данным первичным ключом, используя следующий синтаксис:Subsonic 3 ActiveRecord Удалить/уничтожить странное исключение

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: У меня есть обходное решение от t его ответ, а именно: получить объект с заданным ключом из db, а затем вызвать delete на нем. Он работает, но я хочу знать, почему я получаю это исключение. Также я использую SS 3.0.3 (скачан сегодня (26Jan2K10)).

ответ

1

это похоже на правильную ошибку, так как SubSonicRepository, от которого зависит метод ActiveRecord Destroy, не имеет перегрузки Delete(expression).

Я думаю, что если вы идете в файл шаблона ActiveRecord.tt и найти:

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

и заменить Delete с DeleteMany что удалит все записи возвращает истину для данного выражения (надеюсь, только один, если вам используя первичный ключ :)

GC

+0

выглядит перспективным. Я попробую. – TheVillageIdiot

+0

Я зарегистрировал проблему в проекте Шаблонов на GitHub. –

1

Я не знаком с библиотекой или функцией, но сообщение об ошибке означает, что вы передаете функцию как параметр, где ожидается Int32. И на самом деле вы передаете лямбда-функцию («=>») в качестве параметра Destroy. Итак, первое, что нужно проверить, - это если Destroy действительно хочет функцию или Integer.

Если это не так, обратите внимание, что функция лямбда перенастраивает bool (результат сравнения ==), но ошибка подразумевает, что Int32 требуется. Вы, возможно, придется конвертировать логическое значение в целое, который можно легко сделать с: оператор так:

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

Но, конечно, оба ответа зависит от того, что Уничтожьте параметр на самом деле ожидает.

Смежные вопросы