Frage

Ich verwende Dapper, um einige Lasttest-Tools herauszuarbeiten, die auf eine PostgreSQL-Datenbank zugreifen müssen.Diese spezielle Version von PostgreSQL unterstützt GUIDs nicht nativ, daher werden GUID-Werte als 32-Zeichenfolgen gespeichert.Die Werte werden mit someGuid.ToString("N") in Zeichenfolgen konvertiert. Die Konvertierung zurück in Guid kann mit new Guid(stringValueFromColumn) erfolgen.

Meine Frage ist, wie ich Dapper dazu bringen kann, die Zeichenfolgen zu lesen und sie wieder in Guids umzuwandeln.

Ich habe versucht, die DbType-Zuordnung zu ändern, aber das funktioniert nicht.

War es hilfreich?

Lösung

Der vielleicht einfachste Weg, dies zu tun (ohne auf dapper zu warten), besteht darin, eine zweite Eigenschaft zu haben:

public Guid Foo {get;set;}

public string FooString {
    get { return Foo.ToString("N"); }
    set { Foo = new Guid(value); }
}

Und in Ihrer Abfrage alias die Spalte als FooString.

Dann wirft dies natürlich die Frage auf: Sollte dapper private Eigenschaften für diese Art von Dingen unterstützen?Zu dem sage ich: wahrscheinlich.

Andere Tipps

Ich weiß, dass dies eine alte Frage ist, aber für jeden, der über diesen Thread stolpert, wie ich es heute getan habe, werde ich meine Lösung veröffentlichen.

Ich verwende MySql, aber es gibt das gleiche Problem, da ich die Guid als Zeichenfolge speichere. Um das Mapping zu korrigieren, ohne die Spalte aliasen zu müssen, habe ich Folgendes verwendet:

public class MySqlGuidTypeHandler : SqlMapper.TypeHandler<Guid>
{
    public override void SetValue(IDbDataParameter parameter, Guid guid)
    {
        parameter.Value = guid.ToString();
    }

    public override Guid Parse(object value)
    {
        return new Guid((string)value);
    }
}

Und in meiner Startup.cs:

public void ConfigureServices(IServiceCollection services)
    {
        SqlMapper.AddTypeHandler(new MySqlGuidTypeHandler());
        SqlMapper.RemoveTypeMap(typeof(Guid));
        SqlMapper.RemoveTypeMap(typeof(Guid?));
    }

Dies ist eine alte Frage, aber ich denke, sie muss aktualisiert werden, da Dapper jetzt private Eigenschaften unterstützt, auf die Marc in seiner Antwort verwiesen hat.

private String UserIDString { get; set; }
public Guid UserID
{
    get
    {
        return new Guid(UserIDString);
    }
    private set
    {
        UserID = value;
    }
}

Geben Sie dann in SQL Ihrer ID-Spalte einen Alias, um sie der privaten Eigenschaft und nicht der tatsächlichen Eigenschaft zuzuordnen:

SELECT UserID AS UserIDString FROM....

Ich habe gemeinsam eine Lösung gehackt.Soweit ich das beurteilen kann, gibt es keine Möglichkeit, Dapper anzuweisen, alternativen Bindungscode für einen bestimmten Typ zu generieren. Daher habe ich die GetClassDeserializer-Methode geändert, um den Unbox-Typ zum String zu zwingen, wenn die Eigenschaft eine Guid ist. Als nächstes habe ich den Code wiederverwendet, der einen Konstruktoraufruf für Enums generiert.

Hier ist das geänderte Code-Snippet (beginnend in Zeile 761 von Rev. rf6d62f91f31a):

// unbox nullable enums as the primitive, i.e. byte etc
  var nullUnderlyingType = Nullable.GetUnderlyingType( item.Info.Type );
  var unboxType = nullUnderlyingType != null && nullUnderlyingType.IsEnum ? nullUnderlyingType : item.Info.Type;
  if( unboxType == typeof(Guid))
  {
    unboxType = typeof (string);
  }
  il.Emit( OpCodes.Unbox_Any, unboxType ); // stack is now [target][target][typed-value]
  if (  ( item.Info.Type == typeof( Guid ) && unboxType == typeof( string ) ) 
        || ( nullUnderlyingType != null && nullUnderlyingType.IsEnum ) )
  {
    il.Emit( OpCodes.Newobj, item.Info.Type.GetConstructor( new[] { nullUnderlyingType ?? unboxType} ) );
  }

  il.Emit( OpCodes.Callvirt, item.Info.Setter ); // stack is now [target]

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top