Почему SubSonic и ActiveRecord выдают исключение при обновлении записи? - PullRequest
0 голосов
/ 21 января 2010

У меня есть следующая таблица в 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]

Я использую шаблон 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, так и шаблоны T4 из проекта SubSonic.Tests.

1 Ответ

1 голос
/ 21 января 2010

Мне удалось получить несколько минут, чтобы вернуться к этому и решить.

Меня бросило в глаза то, что я упустил тот факт, что метод 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, чтобы отразить это.

...