هل هناك فئة مضمنة في إطار عمل .Net يمكن استخدامها للإشارة إلى AnsiString؟

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

  •  07-09-2020
  •  | 
  •  

سؤال

بالنسبة للمصمم، أحتاج إلى بناء دعم لتمرير معلمات AnsiString.

تحتوي قواعد البيانات على سلاسل Unicode وسلاسل غير Unicode، ويكون اختيار نوع المعلمة الصحيح أمرًا بالغ الأهمية في بعض الأحيان.

DbType.String ضد DbType.AnsiString لمعلمة معينة يمكن أن تؤثر بشكل كبير على الأداء.

في dapper نقوم بتمرير المعلمات بشكل ديناميكي، على سبيل المثال:

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

لدي خريطة داخلية تقول ذلك إذا رأيت typeof(String) أعرف أن أتمرير في المعلمة كـ a DbType.String

ومع ذلك، أود أن يتمكن المستخدمون من الإشارة إلى أن السلسلة يجب أن تكون AnsiString.السمات غير مدعومة للفئات المجهولة، لذا أحتاج إلى نوع مميز لهذا الغرض.

من الواضح أنه يمكنني اختراع واحد:

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

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

والذي من شأنه أن يمنحني واجهة برمجة التطبيقات النظيفة:

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

ومع ذلك، لماذا نخترع واحدة إذا كانت هذه الفئة موجودة في System.Data أو BCL.

هل هناك نوع في مكان ما في BCL أو System.Data يمكنني استخدامها كحاوية ل AnsiString, ، مع دلالات مماثلة للعينة أعلاه؟

هل كانت مفيدة؟

المحلول

لا يوجد مثل هذه الفئة في BCL أو System.Data، سيتعين عليك إنشاء فئة خاصة بك.

لقد اخترنا نوعًا مخصصًا لتوفير المزيد من التفاصيل الدقيقة في النهاية؛يوضح هذا الاختبار الاستخدام النموذجي:

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

لذا؛انه يدعم:

  • أنسي مقابل يونيكود
  • الطول الثابت مقابل الطول الديناميكي
  • في حالة الطول الديناميكي، الصريح مقابل الضمني (4000 إذا كان الطول <= 4000؛"الحد الأقصى" بخلاف ذلك - وهذا يحافظ على عدد خطط الاستعلام سليمًا)

النوع متوفر بالداخل أنيق.

نصائح أخرى

أعتقد أنه يمكنك استخدامها string ل DbType.String و char[] ل DbType.AnsiString.

سيبدو مشابهًا جدًا لرمزك الحالي:

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

أو إذا كنت تريد استخدام AnsiString، فيمكنك إنشاء طريقة تمديد .ToAnsiString():

public static AnsiString( this string s ) { return new AnsiString(s); }
Query<User>("select * from Users where Name=@Name", new {Name = "name".ToAnsiString()});
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top