views:

202

answers:

1

I have the following table in MS SQL Server 2008 Standard Edition:

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]

I'm using the SubSonic ActiveRecord T4 template and have the following code:

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();
}

The exception thrown is:

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: 

Why is this happening?

Update:

I grabbed the latest source from GitHub but this now breaks the code generated by the T4 template. The generated ActiveRecord.cs won't compile and gives the following build error:

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

The code where this error is happening looks like:

    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();
    }

I did try both the original 3.0.0.3 ActiveRecord template and the T4 templates from the SubSonic.Tests project.

+1  A: 

I managed to get a few moments to revisit this and solve.

The thing that threw me was that I missed the fact that the rdr.Load() method is an extension method (it was ~4am) and had had its method signature changed from:

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

to:

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

Anyway to cut a long story short, once I'd realised this and having done a find usages on the method, all of the calls were just passing null. I then just modified the ActiveRecord.tt T4 template to reflect this.

Kev
Just to clarify what's going on here. The last checkin to the SubSonic repo was to fix Linq projections, it's done that but it's changed the method signature of an extension method and that change needs to propagate downstream to the t4 templates. As you say in your answer anyone can fix this by making sure that their templates pass an extra parameter with a default value of null but it needs fixing so I'll try and find some time to help out with it asap.
Adam
@Adam - I don't mind fixing this over the weekend, plus I get a bit of Git practice and it would be nice to contribute a minor change to the project.
Kev
@Kev - That would be great, go for it.
Adam