2012-09-07 14 views
8

Zacznijmy od usunięcia tego: utknąłem przy użyciu MS Access DB i nie mogę go zmienić.Dapper & MS Access - Czytaj prace, Napisz nie

Działa to dobrze:

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

Działa to dobrze:

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

... To nie jest wykonywany bez błędu, ale ustawia FirstName jako "SomeCity" w DB i Miasto jako "Jan":

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

Jakieś pomysły?

Edycja

Wytworny działa, jeśli mogę użyć 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

To dziwne .. Muszę spróbować powtórzenia błędu ... –

+0

Uwaga: po prostu starał się odtworzyć z SQL Express 2008 i działa dobrze ... –

+0

Robiłem to z powodzeniem z Sql Server ... więc myślę, że jest to z MS Access tylko – Trev

Odpowiedz

8

Po pewnym kopania, udało mi się znaleźć przyczynę:

Poniżej CreateParamInfoGenerator delegat SqlMapper Wytworny za:

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

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

Rekwizyty to Twój jednogłośny param, który zostaje ponownie zamówiony przez OrderBy (p => p.Name), co przenosi miasto z góry.

Rekwizyty są następnie dodawane do IDbCommand Parameters, gdzie kolejność jest ważna.

Jeśli skomentuję polecenie OrderBy(), to wszystko działa.

ja również testowane DynamicParameters i celowo ponownie nakazał przenieść atrybuty miasta upfront:

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

Powyższe nie działa tak dobrze, więc kolejność atrybutów jest powód!

Chyba można modyfikować swoją lokalną kopię SqlMapper teraz i usunąć orderby() i czekać na oficjalny werdykt od Marc ...

nadzieję, że to pomaga.

+1

Okazuje się, że MS Access jest [wybredny co do kolejności parametrów] (http://stackoverflow.com/a/1476818/47121). Próbowałem usunąć kod '.OrderBy (p => p.Name) z SqlMapper i teraz działa. Chciałbym również wiedzieć od Marca lub Sama, czy usunięcie tego kodu będzie miało jakiekolwiek konsekwencje w innym miejscu. – Trev

+0

Ja też tego nie wiedziałem; dobrze wiedzieć! I jestem również ciekawy celu klauzuli OrderBy(). –

+0

Zgodnie z komentarzem do odpowiedzi [tutaj] (http://stackoverflow.com/a/19481354/2144390), nie jest to już problem z aktualną wersją Dappera. –

4

Miałem podobny problem, co zrobiłem to use parameter names like @param1, @param2 zamiast @ nazwa, @ identyfikator, @ cena, więc zamówienie pozostaje takie samo bez konieczności modyfikowania pliku SQLMapper.cs.

Coś

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

Mogło się zmienić rzeczy od czasu ostatniej współpracy z Dapper. Zgodnie z komentarzem do odpowiedzi [tutaj] (http://stackoverflow.com/a/19481354/2144390), nie jest to już problem z bieżącą wersją. –

+1

@GordThompson Dzięki za link. Mam taki sam problem z wersją 1.13 przez NuGet. –

+0

Mam ten sam problem w 1.50.2 – RobinAtTech