2016-07-28 13 views
0

Wenn ich versuche, einen Datensatz enthält Zeichenfolge durch DbString dargestellt deserialisieren:Wie Deserialisieren DbString mit Dapper

class Record 
{ 
    public DbString Text {get; set;} 
} 

ich Fehler

{"Invalid cast from 'System.String' to 'Dapper.DbString'."}

Bin ich DbString in diesem Fall zu mißbrauchen?

Antwort

1

Wenn Sie DbString im Lesemodell verwenden müssen (wie in den Kommentaren zu meiner ersten Antwort beschrieben), dann haben Sie die Möglichkeit, einen Mapper von String zu DbString einzubinden - zB. Definieren Sie die Klasse

public class DbStringTypeHandler : SqlMapper.TypeHandler<DbString> 
{ 
    public override DbString Parse(object value) 
    { 
     if (value == null) 
      return null; 
     var dbStringValue = value as DbString; 
     if (dbStringValue != null) 
      return dbStringValue; 
     var stringValue = value as string; 
     if (stringValue != null) 
      return new DbString { Value = stringValue }; 
     throw new InvalidCastException("Invalid cast from '" + value.GetType() + "' to '" + typeof(DbString) + "'."); 
    } 

    public override void SetValue(IDbDataParameter parameter, DbString value) 
    { 
     parameter.Value = value; 
    } 
} 

und rufen dann

SqlMapper.AddTypeHandler<DbString>(new DbStringTypeHandler()); 

bevor alle Fragen durchführen.

Nun sollte sich die Klasse "Record" sowohl als Lesemodell als auch zum "Schreiben" (dh zum Einstellen von Parametern) gut verhalten.

Getestet habe ich diese mit einer SQL-Server-Verbindung, ich glaube, , dass es die „SqlMapper“ Klasse ist, die Sie brauchen „AddTypeHandler“ zu rufen, unabhängig davon, welche Datenbank Sie sprechen eine Chance, aber es ist, dass Sie Sie müssen dies je nach Anbieter leicht optimieren.

+1

Ich fühle mich wie ein Downvote ist ein wenig hart (in Bezug auf den jetzt entfernten Kommentar zu fragen, warum ich zwei Antworten hinterlassen hatte)! Meine ursprüngliche Antwort ist, glaube ich, gültig für die ursprüngliche Frage, wie sie ursprünglich (und immer noch) angegeben wurde; In den meisten Fällen wäre es besser, eine "string" -Eigenschaft für die Record-Klasse als "DbString" zu verwenden. Wenn die Frage jedoch im neuen Licht betrachtet wird (wie @ironic in Kommentaren zu meiner ersten Antwort geklärt hat), ist meine zweite (und völlig andere) Antwort anwendbar. –

+0

nur für den Fall - Ich habe Ihre Antworten nicht downvote! Ich werde sie sogar auffrischen, weil ich dankbar bin, dass ich ihnen helfen kann! – ironic

+0

Danke. Ich denke, es war jemand, der einen kleinen Treffer gemacht hat und die Frage beantwortet hat - nachdem er gesehen hatte, dass ich zwei von ihnen zurückgelassen hatte und einen Kommentar hinterlassen hatte, warum er gefragt wurde. Als ich geantwortet habe, haben sie ihren Kommentar entfernt, aber die Stimmen abgegeben. Ich weiß es zu schätzen, dass Sie das Gleichgewicht wieder gefunden haben! :) –

1

Die Idee mit Dapper ist es, Abfrageergebnisse in standardmäßige .net-Klassen zu übersetzen.

Der Typ "DbString" ist eine Dapper-Klasse, die für die Angabe von Parameterwerten in einer bestimmten Weise verwendet wird, es ist nicht etwas "Standard-.net".

Also, anstatt zu versuchen, zu erraten, welche Typen, denen Dapper die Dinge zuordnen könnte, sollten Sie mit dem einfachsten Fall beginnen, da Dapper sehr oft einfach funktionieren wird.

In Ihrem Fall sollten Sie Ihre Aufzeichnung einfach sein

class Record 
{ 
    public string Text { get; set; } 
} 

Dapper einige Arbeit tun, um zu versuchen, um sicherzustellen, dass jeder vernünftige Typkonvertierungen behandelt werden - ein int zum Beispiel, wenn Sie Ihre Datenbankfeld dann ist wird dies gerne einer Int-Eigenschaft auf dem C# -Typ oder zu einem langen oder zu einem kurzen oder einem Byte zuordnen (obwohl Sie das Risiko einer Überlaufausnahme zur Laufzeit laufen lassen, wenn Sie auf einen kleineren Datentyp ablaufen). Zusammenfassend ist Dapper gut für Sie und versucht die harte Arbeit des Type Mappings zu erledigen - Sie können sich grundsätzlich an die Grundlagen halten (String, anstatt sich Gedanken darüber zu machen, ob Sie vielleicht DbString verwenden) und Dapper wird Sie aussortieren!

+0

Sie voreiligen Schlüsse zu schnell, mein Freund. Das erste, was zu erwähnen ist - wir müssen lesen und schreiben. Ich begann tatsächlich mit einer einfachen Zeichenfolge. aber wir verwenden sql anywhere data provider, der eine Ausnahme auslöst, wenn DbParameter.Length auf -1 gesetzt wird (was sich von OdbcParameter unterscheidet, wo es gut funktioniert). Also habe ich herausgefunden, dass ich mit DbString dieses Problem umgehen kann. – ironic

+0

habe ich auch überlegt, DbStrings nur dann zu verwenden, wenn ich sie zum Schreiben von Abfragen übergebe, aber das bedeutet, dass ich Parameterobjekte manuell erstellen muss, anstatt nur meine Datensätze zu übergeben. Mit all dem oben genannten kann ich, wenn ich die Bestätigung bekommen kann, dass DbString als Feldtyp verwendet werden soll, einfach auf eine Korrektur warten. Sonst werde ich wahrscheinlich zu String + manual parameter object zurückkehren. – ironic