2012-09-07 8 views
8

Iniziamo facendo questo: Sono bloccato utilizzando un MS Access DB e non posso cambiarlo.Accesso Dapper & MS - Lettura delle opere, Scrittura non

Questo funziona bene:

using (OleDbConnection conn = ConnectionHelper.GetConnection()) 
{ 
    conn.Open(); 
    var results = conn.Query<string>(
    "select FirstName from Students where LastName = @lastName", 
    new { lastName= "Smith" } 
); 
    conn.Close(); 
} 

Questo funziona bene:

using (OleDbConnection conn = ConnectionHelper.GetConnection()) 
{ 
    OleDbCommand cmd = new OleDbCommand(
    "update Students set FirstName = @firstName, City = @city where LastName = @lastName", 
    conn 
); 
    cmd.Parameters.AddWithValue("firstName", "John"); 
    cmd.Parameters.AddWithValue("city", "SomeCity"); 
    cmd.Parameters.AddWithValue("lastName", "Smith"); 

    conn.Open(); 
    var result = cmd.ExecuteNonQuery(); 
    conn.Close(); 
} 

questo non ... esegue senza errori, ma imposta il FirstName come "SomeCity" nel DB e la città come "John":

using (OleDbConnection conn = ConnectionHelper.GetConnection()) 
{ 
    conn.Open(); 
    var results = conn.Query<string>(
    "update Students set FirstName = @firstName, City = @city where LastName = @lastName", 
    new { firstName = "John", city = "SomeCity", lastName = "Smith" } 
); 
    conn.Close(); 
} 

Qualche idea?

modifica sotto

Dapper funziona se uso DynamicParameters:

using (OleDbConnection conn = ConnectionHelper.GetConnection()) 
{ 
    DynamicParameters parameters = new DynamicParameters(); 
    parameters.Add("firstName", "John"); 
    parameters.Add("city", "SomeCity"); 
    parameters.Add("lastName", "Smith"); 

    conn.Open(); 
    var result = conn.Query<string>(
    "update Students set FirstName = @firstName, City = @city where LastName = @lastName", 
    parameters 
); 
    conn.Close(); 
} 
+0

Questo è strano .. Ho bisogno di provare a Repro ... –

+0

Nota: Solo cercato di riprodurre con SQL Express 2008 e funziona benissimo ... –

+0

ho fatto questo con successo con Sql Server ... quindi penso che questo sia con MS Access solo – Trev

risposta

8

Dopo un po 'di scavo, sono stato in grado di trovare una causa:

Di seguito è CreateParamInfoGenerator delegato SqlMapper di Dapper:

public static Action<IDbCommand, object> CreateParamInfoGenerator(Identity identity) 
    { 

     // code above here 
     IEnumerable<PropertyInfo> props = type.GetProperties().OrderBy(p => p.Name); 

Il materiale di scena è il tuo parametro unanime che viene riordinato da OrderBy (p => p.Name), che sposta la città in anticipo.

new { firstName = "John", city = "SomeCity", lastName = "Smith" } 

I puntatori vengono quindi aggiunti ai parametri IDbCommand in cui l'ordine è importante.

Se commento la clausola OrderBy(), quindi tutto funziona.

DynamicParameters Ho anche testato e intenzionalmente riordinati gli attributi per muoversi città in anticipo:

 var parameters = new DynamicParameters(); 
     parameters.Add("city", "SomeCity"); 
     parameters.Add("firstName", "John"); 
     parameters.Add("lastName", "Smith"); 

     var result = dbConnection.Query<string>(
      "update Students set FirstName = @firstName, City = @city where LastName = @lastName", 
      parameters 
     ); 

È possibile che questo non ha funzionato e, in modo l'ordine degli attributi è la ragione!

Credo che si può modificare la propria copia locale del SqlMapper per ora e rimuovere OrderBy() e attendere un verdetto ufficiale del Marc ...

Spero che questo aiuti.

+1

Si scopre che MS Access è [pignolo per l'ordine dei parametri] (http://stackoverflow.com/a/1476818/47121). Ho provato a rimuovere il codice '.OrderBy (p => p.Name)' da SqlMapper e ora funziona. Mi piacerebbe anche sapere da Marc o Sam se rimuovere questo codice avrebbe delle implicazioni altrove. – Trev

+0

Non lo sapevo bene; buono a sapersi! E sono anche curioso dello scopo della clausola OrderBy(). –

+0

In base a un commento alla risposta [qui] (http://stackoverflow.com/a/19481354/2144390), questo non è più un problema con la versione corrente di Dapper. –

4

Avevo un problema simile, quello che ho fatto è stato a use parameter names like @param1, @param2 anziché @ nome, @ id, @ prezzo, quindi l'ordine rimane lo stesso senza dover modificare il file SQLMapper.cs.

Qualcosa di simile

public void Update(Movie movie) 
{ 
    var sql = "UPDATE myDB.movies set [email protected], [email protected] where [email protected]"; 
    db.Execute(sql, new { param1 = movie.Title, param2 = movie.Genre, param3 = movie.ID }); 
} 
+0

Le cose potrebbero essere cambiate dall'ultima volta che hai lavorato con Dapper. Secondo un commento alla risposta [qui] (http://stackoverflow.com/a/19481354/2144390), questo non è più un problema con la versione corrente. –

+1

@GordThompson Grazie per il link. Sto avendo lo stesso problema con la versione 1.13 via NuGet. –

+0

Ho lo stesso problema in 1.50.2 – RobinAtTech

Problemi correlati