Update-Abfrage führt zu nichts

asp.net-mvc c# dapper ms-access orm

Frage

Ich versuche die folgende Abfrage aufzurufen (Parameter sind in alphabetischer Reihenfolge):

public const string UpdateSample =
    @"UPDATE subReceivingQC
      SET Clerk=@Clerk, Comments=@Comments, CommentsProd=@CommentsProd, GRV=@GRV, 
          MassOff=@MassOff, PalletID=@PalletID, PalletSeq=@PalletSeq, PONo=@PONo, 
          QCDate=@QCDate, QtyInspected=@QtyInspected, SampleNo=@SampleNo, 
          StatusClerk=@StatusClerk, StatusSupervisor=@StatusSupervisor, Supervisor=@Supervisor
      WHERE GRV=@GRV AND PalletSeq=@PalletSeq AND SampleNo=@SampleNo;";

Mit dieser Methode:

internal int UpdateSample(Sample sample)
{
    using (var db = new OleDbConnection(ConnectionString))
    {
        var query = Constants.UpdateSample;
        return db.Execute(query, sample);
    }
}

Der Befehl Execute() ist erfolgreich (es werden keine Ausnahmen UpdateSample ), aber UpdateSample 0 und der Datenbankeintrag bleibt unverändert.

Ich habe dieses genaue Muster für andere db-Operationen ( INSERT und SELECT ) ohne irgendein Problem verwendet.

Die einzigen verwandten Probleme, die ich finden kann, wurden gelöst, indem die Parameter in der Abfrage sortiert wurden (meins ist bereits sortiert).

Hat jemand irgendwelche Einsichten darüber, was hier vor sich geht oder wie ich das Problem beheben kann?

Nach Steves Kommentar habe ich keinen Code zum Hinzufügen von Parametern zum Befehl hinzugefügt, da ich den Eindruck habe, dass diese automatisch vom Model .


Im Sample verfügbare Eigenschaften:

public class Sample : IGriddable
{
    public string[] ColumnHeaders { get; } = new string[] { "SampleNo", "QCDate", "StatusClerk", "StatusSupervisor" };
    public string RowLinkPrefix { get { return $"/receiving/{Pallet.Grv.GRVNo}/{Pallet.PalletSeq}/"; } }
    public bool Selectable { get; } = true;

    public Pallet Pallet { get; set; }

    public string Clerk { get; set; }
    public string MassOff { get; set; }
    public string CommentsProd { get; set; }
    public string QtyInspected { get; set; }
    public string Supervisor { get; set; }
    public string Comments { get; set; } 

    public string SampleNo { get; set; }
    public string StatusClerk { get; set; }
    public string StatusSupervisor { get; set; }
    public string ProductSpec { get; set; }

    // For required db params
    public string GRV { get; set; }
    public string PalletID { get; set; }
    public string PalletSeq { get; set; }
    public string PONo { get; set; }

    [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
    public DateTime QCDate { get; set; }

    // Each defect status needs to be saved as a (DB)subQCItems item
    public List<QCItem> Defects { get; set; } = new List<QCItem>();
    public List<string> ImagePaths { get; set; } = new List<string>();
}

Akzeptierte Antwort

OleDb erfordert, dass Sie die Parameter genau in der Reihenfolge übergeben, in der Sie sie im Befehlstext darstellen. Wenn Sie es nicht tun, könnten falsche Werte für die WHERE-Anweisung verwendet werden, und wenn Sie Pech haben, können Sie damit aufhören, einen falschen Datensatz zu ändern, oder Sie aktualisieren einfach nichts.

Leider berücksichtigt Dapper dies nicht in seinen Algorithmen, die zur Vorbereitung des Befehls verwendet werden. Sql Server und andere Anbieter mit benannten Parametern und keine Einschränkungen für die Reihenfolge haben dieses Problem nicht. Anstatt den Code hinzuzufügen, um die Parameter basierend auf dem Abfragetext korrekt zu erstellen und zu sortieren, kann dies sehr kostspielig sein.
Ich glaube, dass sie dachten, dass dies die Mühe nicht wert war und dass Sie einfach das Problem lösen können, indem Sie sich die Parameter definieren.

Sie sind also in diesem Punkt allein und Sie sollten die Version von Execute verwenden, die einen DynamicParameters-Parameter verwendet

using (var db = new OleDbConnection(ConnectionString))
{
    var query = Constants.UpdateSample;

    DynamicParameters pars = new DynamicParameters();
    pars.Add("@Clerk", sample.Clerk, DbType.String);
    // ... and so on for all parameters following the order of the placeholders

    // but end with ....
    pars.Add("@GRV", sample.GRV, DbType.String);
    pars.Add("@PalletSeq", sample.PalletSeq, DbType.String);
    pars.Add("@SampleNo", sample.SampleNo, DbType.String);

    return db.Execute(query, pars);
}

Beliebte Antwort

Welche Datenbank verwendest du? Wenn SQL Server verwendet wird, verwenden Sie SQL Profiler, um die genaue Abfrage herauszufinden, die ausgeführt wird.

Wenn Sie keinen SQL-Server verwenden, versuchen Sie, die Abfrage selbst ohne oledb in der Datenbank auszuführen. Es ist wahrscheinlich ein Parameterproblem, bei dem die Where-Klausel zu keinen Ergebnissen führt. Welchen Wert haben @GRV, @PalletSeq und @SampleNo? Wenn keine Datensätze mit dieser Kombination übereinstimmen, passiert offensichtlich nichts



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum