2013-07-17 11 views
5

Sto tentando di interrogare il mio db utilizzando Enumerable.Contains all'interno di una clausola SqlExpressionVisitor.Where. Quando viene compilato il lambda, sto ricevendo un'eccezione di riferimento null.Ormlite Where-Contains Fails

Quando il visitatore rende a foreach (Object e in inArgs) (attualmente linea 1067) all'interno SqlExpressionVisitor.VisitArrayMethodCall, soffoca perché inArgs è nullo. Quello che segue è il mio esempio che causa l'errore. Non capisco abbastanza bene le espressioni/espressioni lambda per sapere perché questo sta accadendo.

Quindi le mie domande sono, non sto utilizzando correttamente la clausola Where o si tratta di un bug?

class Program 
{ 
    static void Main(string[] args) 
    { 
     var connectionFactory = new OrmLiteConnectionFactory(@"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|Database1.mdf;Integrated Security=True;User Instance=True", SqlServerDialect.Provider); 
     SetupDb(connectionFactory);   

     using (var db = connectionFactory.OpenDbConnection()) 
     { 
      var numbersToSelect = new int[2] { 1, 2 }; 
      db.Select<SomeObject>(e => e.Where(o => numbersToSelect.Contains(o.Number))); 
     } 
    } 

    static void SetupDb(IDbConnectionFactory connectionFactory) 
    { 
     using (var db = connectionFactory.OpenDbConnection()) 
     { 
      db.DropTable<SomeObject>(); 
      db.CreateTable<SomeObject>(); 
      db.Insert(new SomeObject { Number = 1 }); 
      db.Insert(new SomeObject { Number = 2 }); 
      db.Insert(new SomeObject { Number = 3 }); 
      db.Insert(new SomeObject { Number = 4 }); 
      db.Insert(new SomeObject { Number = 5 }); 
     } 
    } 
} 

class SomeObject 
{ 
    public int Number { get; set; } 
} 

Dopo un po 'più di scavo, si scopre chiamando il metodo compilato restituisce un int[] che provoca il cast object[] essere nullo. La trasmissione a IEnumerable risolve il mio problema specifico.

Modificato

var getter = lambda.Compile(); 
var inArgs = getter() as object[]; 

a

var getter = lambda.Compile(); 
var inArgs = getter() as IEnumerable; 

Non so che tipo di implicazioni questo ha però (se presente). Sto ancora cercando una guida.

+0

sembra che ci fosse un aggiornamento per il repository ORMLite circa [6 ore fa] (https://github.com/ServiceStack/ServiceStack.OrmLite/commit/9f0b0e8cfa4410da5d288bf754ba6538805cbec0) relativi a questo aspetto specifico. – Mike

risposta

2

Abbiamo scoperto che era un bug. È stato corretto per il visitatore sqlite e per il visitatore sql a partire da commit 9f0b0e8 Grazie a @mythz.

8

Invece di usare Contiene, utilizzare Sql.In

db.Select<SomeObject>(e => e.Where(o => Sql.In(o.Number,numbersToSelect)));

+0

'Sql.In' non funziona su negozi non sql (' Elenco '). Il codice effettivo che ho è in un livello di servizio che chiama i repository che prendono un'espressione come parametro. – Chris