2010-01-21 67 views
-1

我在MS SQL Server 2008標準版如下表:爲什麼SubSonic和ActiveRecord在更新記錄時拋出異常?

CREATE TABLE [dbo].[NewTestQueue](
    [JobID] [int] IDENTITY(1,1) NOT NULL, 
    [ServerName] [varchar](50) NULL, 
    [DomainID] [int] NOT NULL, 
    [Action] [varchar](50) NULL, 
    [Folder] [varchar](150) NULL, 
    [Method] [varchar](50) NULL, 
    [ActionProfile] [varchar](50) NULL, 
    [Title] [varchar](150) NULL, 
    [Suffix] [varchar](50) NULL, 
    [Host] [varchar](150) NULL, 
    [Url] [varchar](250) NULL, 
    [Expression] [varchar](50) NULL, 
    [MasterTest] [varchar](50) NULL, 
    [Completed] [bit] NOT NULL 
) ON [PRIMARY] 

我使用SubSonic ActiveRecord T4模板,並有下面的代碼:

var tests = NewTestQueue.Find(d => !d.Completed); 
foreach(var test in tests) 
{ 
    // Do some work with test 
    // ... 

    // Now mark job as completed 
    test.Completed = true; 

    // System.NullReferenceException thrown here 
    test.Update(); 
} 

引發的異常是:

System.NullReferenceException was unhandled 
    Message="Object reference not set to an instance of an object." 
    Source="SubSonic.Core" 
    StackTrace: 
     at SubSonic.Extensions.Database.ToUpdateQuery[T](T item, IDataProvider provider) 
     at SubSonic.Repository.SubSonicRepository`1.Update(T item, IDataProvider provider) 
     at HostMonitor.NewTestQueue.Update(IDataProvider provider) in E:\AppsDev.NET\_UK_Minds\Tollon Components\HostMonitor\Tollon.HostMonitor.TestGenerator\ActiveRecord\ActiveRecord.cs:line 593 
     at HostMonitor.NewTestQueue.Update() in E:\AppsDev.NET\_UK_Minds\Tollon Components\HostMonitor\Tollon.HostMonitor.TestGenerator\ActiveRecord\ActiveRecord.cs:line 586 
     at Tollon.HostMonitor.TestGenerator.Program.Main(String[] args) in E:\AppsDev.NET\_UK_Minds\Tollon Components\HostMonitor\Tollon.HostMonitor.TestGenerator\Program.cs:line 46 
     at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args) 
     at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
     at System.Threading.ThreadHelper.ThreadStart() 
    InnerException: 

這是怎麼發生的?

更新:

我抓住了最新的源從GitHub但現在打破由T4模板生成的代碼。生成的ActiveRecord.cs將無法​​編譯,並給出了下面的生成錯誤:

No overload for method 'Load' takes '1' arguments 
[Path snipped]\subsonic-SubSonic-3.0-4748517\SubSonic.Tests\BugReports\Generated\ActiveRecord.cs  
Line: 708 

這個地方發生錯誤的代碼如下:

public void Load(IDataReader rdr) { 
     Load(rdr, true); 
    } 
    public void Load(IDataReader rdr, bool closeReader) { 
     if (rdr.Read()) { 

      try { 
       rdr.Load(this); // <<-- Compile error happens here 
       SetIsNew(false); 
       SetIsLoaded(true); 
      } catch { 
       SetIsLoaded(false); 
       throw; 
      } 
     }else{ 
      SetIsLoaded(false); 
     } 

     if (closeReader) 
      rdr.Dispose(); 
    } 

我曾嘗試無論是原3.0.0.3的ActiveRecord模板來自SubSonic.Tests項目的T4模板。

回答

1

我設法得到了一些時刻來重新審視和解決。

拋出我的是,我錯過了一個事實,即rdr.Load()方法是一個擴展方法的東西(它〜凌晨4點),並有其方法簽名變更情況:從

public static void Load<T>(this IDataReader rdr, T item) 

到:

public static void Load<T>(this IDataReader rdr, T item, List<string> ColumnNames) 

反正削減長話短說,有一次,我意識到這一點,並已經做了該方法的發現用途,所有的呼叫都只是路過null。然後我修改了ActiveRecord.tt T4模板來反映這一點。

+0

只是爲了澄清這裏發生了什麼。最後簽入SubSonic回購協議是爲了修復Linq預測,它已經完成了,但它改變了擴展方法的方法簽名,並且該更改需要向下遊傳播到t4模板。正如你在答案中所說的,任何人都可以通過確保他們的模板傳遞一個默認值爲null的額外參數來解決這個問題,但它需要修復,所以我會盡力找到一些時間來幫助它。 – 2010-01-21 20:45:27

+0

@Adam - 我不介意在週末修復這個問題,再加上我有一點Git的實踐經驗,很高興能爲項目做一些小改動。 – Kev 2010-01-22 01:42:18

+0

這將是偉大的,去爲它。 – 2010-01-22 08:40:58

相關問題