Gibt es im .Net-Framework eine integrierte Klasse, die zur Bezeichnung eines AnsiStrings verwendet werden kann?

StackOverflow https://stackoverflow.com/questions/6069021

  •  07-09-2020
  •  | 
  •  

Frage

Für Dapper muss ich Unterstützung für die Übergabe von AnsiString-Parametern aufbauen.

Da Datenbanken sowohl Unicode- als auch Nicht-Unicode-Zeichenfolgen enthalten, ist die Auswahl des richtigen Parametertyps manchmal entscheidend.

DbType.String vs DbType.AnsiString denn ein bestimmter Parameter kann die Leistung stark beeinflussen.

In Dapper übergeben wir Parameter dynamisch, z. B.:

Query<User>("select * from Users where Name=@Name", new {Name = "name"});

Ich habe eine interne Karte, die das sagt, wenn ich es sehe typeof(String) Ich weiß, dass ich den Parameter als a übergeben muss DbType.String

Ich möchte jedoch, dass meine Benutzer angeben können, dass die Zeichenfolge ein AnsiString sein soll.Attribute werden für anonyme Klassen nicht unterstützt, daher benötige ich hierfür einen eindeutigen Typ.

Offensichtlich kann ich eines erfinden:

public class AnsiString 
{
    private readonly string str;
    public AnsiString(string str)
    {
        this.str = str;
    }

    public String Value { get { return str; } }
}

Was mir die saubere API geben würde:

Query<User>("select * from Users where Name=@Name", 
   new {Name = new AnsiString("name")});

Warum jedoch eine erfinden, wenn eine solche Klasse in System.Data oder der BCL vorhanden ist?

Gibt es irgendwo in der BCL einen Typ bzw System.Data Ich könnte es als Behälter für verwenden AnsiString, mit ähnlicher Semantik wie im obigen Beispiel?

War es hilfreich?

Lösung

Es gibt keine solche Klasse in der BCL oder System.Data, Sie müssen Ihre eigene rollen.

Wir haben uns für einen benutzerdefinierten Typ entschieden, um letztendlich eine feinere Anpassung zu ermöglichen.Dieser Test zeigt die typische Verwendung:

public void TestDbString()
{
    var obj = connection.Query("select datalength(@a) as a, datalength(@b) as b, datalength(@c) as c, datalength(@d) as d, datalength(@e) as e, datalength(@f) as f",
        new
        {
            a = new DbString { Value = "abcde", IsFixedLength = true, Length = 10, IsAnsi = true },
            b = new DbString { Value = "abcde", IsFixedLength = true, Length = 10, IsAnsi = false },
            c = new DbString { Value = "abcde", IsFixedLength = false, Length = 10, IsAnsi = true },
            d = new DbString { Value = "abcde", IsFixedLength = false, Length = 10, IsAnsi = false },
            e = new DbString { Value = "abcde", IsAnsi = true },
            f = new DbString { Value = "abcde", IsAnsi = false },
        }).First();
    ((int)obj.a).IsEqualTo(10);
    ((int)obj.b).IsEqualTo(20);
    ((int)obj.c).IsEqualTo(5);
    ((int)obj.d).IsEqualTo(10);
    ((int)obj.e).IsEqualTo(5);
    ((int)obj.f).IsEqualTo(10);
}

Also;es unterstützt:

  • Ansi vs. Unicode
  • feste vs. dynamische Länge
  • bei dynamischer Länge: explizit vs. implizit (4000, wenn die Länge <= 4000 ist;andernfalls „max“ – dies hält die Anzahl der Abfragepläne im Rahmen)

Der Typ ist innen erhältlich elegant.

Andere Tipps

Ich denke, Sie können es verwenden string für DbType.String Und char[] für DbType.AnsiString.

Es wird Ihrem aktuellen Code sehr ähnlich sehen:

Query<User>("select * from Users where Name=@Name", new {Name = "name".ToCharArray()});

Wenn Sie Ihren AnsiString verwenden möchten, können Sie auch eine Erweiterungsmethode erstellen .ToAnsiString():

public static AnsiString( this string s ) { return new AnsiString(s); }
Query<User>("select * from Users where Name=@Name", new {Name = "name".ToAnsiString()});
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top