2010-01-21 12 views
-1

je le tableau suivant dans MS SQL Server 2008 Standard Edition:Pourquoi SubSonic et ActiveRecord lancent une exception lors de la mise à jour d'un enregistrement?

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] 

J'utilise le modèle T4 SubSonic ActiveRecord et ont le code suivant:

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

L'exception levée est:

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: 

Pourquoi cela se produit-il?

Mise à jour:

J'ai attrapé la dernière source GitHub mais rompt maintenant le code généré par le modèle T4. Le produit ActiveRecord.cs ne compilera pas et donne l'erreur de compilation suivante:

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

Le code où cette erreur se produit ressemble à:

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

J'ai essayé à la fois le modèle ActiveRecord 3.0.0.3 original et les modèles T4 du projet SubSonic.Tests.

Répondre

1

J'ai réussi à obtenir quelques instants pour revisiter ceci et résoudre.

La chose qui m'a jeté était que je manqué le fait que la méthode rdr.Load() est une méthode d'extension (il était ~ 4 heures) et avait eu la signature de la méthode modifiée de:

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

à:

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

Quoi qu'il en soit pour couper une longue histoire courte, une fois que je l'avais réalisé cela et avoir fait usages de trouver sur la méthode, tous les appels ne faisaient que passer null. Je viens ensuite de modifier le modèle T4 ActiveRecord.tt pour refléter cela.

+0

Juste pour clarifier ce qui se passe ici. La dernière vérification du repo SubSonic consistait à corriger les projections de Linq, c'est fait, mais il a changé la signature de méthode d'une méthode d'extension et cette modification doit se propager en aval des templates t4. Comme vous le dites dans votre réponse, n'importe qui peut corriger cela en s'assurant que leurs templates passent un paramètre supplémentaire avec une valeur par défaut de null mais il doit être réparé, donc je vais essayer de trouver un peu de temps pour l'aider. –

+0

@Adam - Cela ne me dérange pas de résoudre ce problème au cours du week-end, en plus je reçois un peu de pratique de Git et il serait bien d'apporter une petite modification au projet. – Kev

+0

Ce serait génial, allez-y. –