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

为什么亚音速和ActiveRecord在更新记录时引发异常?

  •  -1
  • erlando  · 技术社区  · 15 年前

    我在MS SQL Server 2008标准版中有下表:

    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 项目。

    1 回复  |  直到 15 年前
        1
  •  1
  •   erlando    15 年前

    我设法花了点时间重新考虑这个问题并解决。

    令我震惊的是我错过了 rdr.Load() 方法是一个扩展方法(它 ~4am)并已将其方法签名从以下更改为:

    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模板反映了这一点。