تقع في https://github.com/dapperlib/dapper/release
Myget Pre-Rlease Feed: https://www.myget.org/gallery/dapper
طَرد | nuget مستقر | Nuget قبل الإصدار | التنزيلات | myget |
---|---|---|---|---|
Dapper | ||||
dapper.entityframework | ||||
dapper.entityframework.strongName | ||||
Dapper.RainBow | ||||
dapper.sqlbuilder | ||||
dapper.strongName |
أغراض الحزمة:
تم تطوير Dapper في الأصل من أجل و Overflow Stack ، ولكن F/OSS. الرعاية ترحيب ودعوة - راجع رابط الراعي في الجزء العلوي من الصفحة. شكر كبير للجميع (الأفراد أو المنظمات) الذين قاموا برعاية Dapper ، ولكن شكر كبير على وجه الخصوص ل:
Dapper هي مكتبة Nuget يمكنك إضافتها إلى مشروعك الذي سيعزز اتصالات ADO.NET عبر طرق التمديد على مثيل DbConnection
الخاص بك. يوفر هذا واجهة برمجة تطبيقات بسيطة وفعالة لاستدعاء SQL ، مع دعم لكل من الوصول إلى البيانات المتزامن وغير المتزامن ، ويسمح لكل من الاستعلامات المخزنة وغير المخزنة.
يوفر العديد من المساعدين ، لكن واجهات برمجة التطبيقات الرئيسية هي:
// insert/update/delete etc
var count = connection . Execute ( sql [ , args ] ) ;
// multi-row query
IEnumerable < T > rows = connection . Query < T > ( sql [ , args ] ) ;
// single-row query ({Single|First}[OrDefault])
T row = connection . QuerySingle < T > ( sql [ , args ] ) ;
حيث يمكن أن يكون args
(من بين أشياء أخرى):
Dictionary<string,object>
DynamicParameters
public class Dog
{
public int ? Age { get ; set ; }
public Guid Id { get ; set ; }
public string Name { get ; set ; }
public float ? Weight { get ; set ; }
public int IgnoredProperty { get { return 1 ; } }
}
var guid = Guid . NewGuid ( ) ;
var dog = connection . Query < Dog > ( " select Age = @Age, Id = @Id " , new { Age = ( int ? ) null , Id = guid } ) ;
Assert . Equal ( 1 , dog . Count ( ) ) ;
Assert . Null ( dog . First ( ) . Age ) ;
Assert . Equal ( guid , dog . First ( ) . Id ) ;
ستقوم هذه الطريقة بتنفيذ SQL وإرجاع قائمة ديناميكية.
مثال الاستخدام:
var rows = connection . Query ( " select 1 A, 2 B union all select 3, 4 " ) . AsList ( ) ;
Assert . Equal ( 1 , ( int ) rows [ 0 ] . A ) ;
Assert . Equal ( 2 , ( int ) rows [ 0 ] . B ) ;
Assert . Equal ( 3 , ( int ) rows [ 1 ] . A ) ;
Assert . Equal ( 4 , ( int ) rows [ 1 ] . B ) ;
مثال الاستخدام:
var count = connection . Execute ( @"
set nocount on
create table #t(i int)
set nocount off
insert #t
select @a a union all select @b
set nocount on
drop table #t" , new { a = 1 , b = 2 } ) ;
Assert . Equal ( 2 , count ) ;
يتيح لك التوقيع نفسه أيضًا تنفيذ أمر مريح وكفاءة عدة مرات (على سبيل المثال لبيانات التحميل بالجملة)
مثال الاستخدام:
var count = connection . Execute ( @"insert MyTable(colA, colB) values (@a, @b)" ,
new [ ] { new { a = 1 , b = 1 } , new { a = 2 , b = 2 } , new { a = 3 , b = 3 } }
) ;
Assert . Equal ( 3 , count ) ; // 3 rows inserted: "1,1", "2,2" and "3,3"
مثال آخر استخدام عندما يكون لديك بالفعل مجموعة موجودة:
var foos = new List < Foo >
{
{ new Foo { A = 1 , B = 1 } }
{ new Foo { A = 2 , B = 2 } }
{ new Foo { A = 3 , B = 3 } }
} ;
var count = connection . Execute ( @"insert MyTable(colA, colB) values (@a, @b)" , foos ) ;
Assert . Equal ( foos . Count , count ) ;
هذا يعمل مع أي معلمة تنفذ IEnumerable<T>
لبعض T.
ميزة رئيسية من Dapper هي الأداء. توضح المقاييس التالية المدة التي يستغرقها تنفيذ عبارة SELECT
مقابل ديسيبل (في التكوين المختلفة ، كل علامة عليها) ورسم خريطة البيانات التي يتم إرجاعها إلى الكائنات.
يمكن العثور على المعايير في dapper.tests.performance (الترحيب بالمساهمات!) ويمكن تشغيله عبر:
dotnet run --project . b enchmarks D apper.Tests.Performance -c Release -f net8.0 -- -f * --join
الإخراج من آخر تشغيل هو:
BenchmarkDotNet v0.13.7, Windows 10 (10.0.19045.3693/22H2/2022Update)
Intel Core i7-3630QM CPU 2.40GHz (Ivy Bridge), 1 CPU, 8 logical and 4 physical cores
.NET SDK 8.0.100
[Host] : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX
ShortRun : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX
orm | طريقة | يعود | يقصد | Stddev | خطأ | Gen0 | Gen1 | Gen2 | مخصص |
---|---|---|---|---|---|---|---|---|---|
تأثير ذاكرة التخزين المؤقت Dapper | executeParameters_Cache | فارغ | 96.75 لنا | 0.668 لنا | 1.010 لنا | 0.6250 | - | - | 2184 ب |
تأثير ذاكرة التخزين المؤقت Dapper | QueryFirstParameters_Cache | فارغ | 96.86 لنا | 0.493 لنا | 0.746 لنا | 0.8750 | - | - | 2824 ب |
ترميز اليد | SqlCommand | بريد | 119.70 لنا | 0.706 الولايات المتحدة | 1.067 لنا | 1.3750 | 1.0000 | 0.1250 | 7584 ب |
ترميز اليد | DataTable | متحرك | 126.64 الولايات المتحدة | 1.239 لنا | 1.873 لنا | 3.0000 | - | - | 9576 ب |
Sqlmarshal | SqlCommand | بريد | 132.36 لنا | 1.008 الولايات المتحدة | 1.523 لنا | 2.0000 | 1.0000 | 0.2500 | 11529 ب |
Dapper | QueryFirstordefault | بريد | 133.73 لنا | 1.301 لنا | 2.186 لنا | 1.7500 | 1.5000 | - | 11608 ب |
أقوياء | استفسار | متحرك | 133.92 لنا | 1.075 لنا | 1.806 لنا | 2.0000 | 1.7500 | - | 12710 ب |
LINQ إلى DB | استفسار | بريد | 134.24 الولايات المتحدة | 1.068 لنا | 1.614 لنا | 1.7500 | 1.2500 | - | 10904 ب |
repoDB | executequery | بريد | 135.83 لنا | 1.839 لنا | 3.091 لنا | 1.7500 | 1.5000 | - | 11649 ب |
Dapper | "استعلام (مخزنة)" | بريد | 136.14 لنا | 1.755 لنا | 2.653 لنا | 2.0000 | 1.5000 | - | 11888 ب |
أقوياء | استفسار | بريد | 137.96 لنا | 1.485 لنا | 2.244 الولايات المتحدة | 2.2500 | 1.2500 | - | 12201 ب |
Dapper | QueryFirstordefault | متحرك | 139.04 لنا | 1.507 لنا | 2.279 لنا | 3.5000 | - | - | 11648 ب |
أقوياء | SingleFromquery | متحرك | 139.74 لنا | 2.521 لنا | 3.811 لنا | 2.0000 | 1.7500 | - | 12710 ب |
Dapper | "استعلام (مخزنة)" | متحرك | 140.13 لنا | 1.382 لنا | 2.090 لنا | 2.0000 | 1.5000 | - | 11968 ب |
Servicestack | واحد | بريد | 140.76 لنا | 1.147 لنا | 2.192 لنا | 2.5000 | 1.2500 | 0.2500 | 15248 ب |
Dapper | "contrib get" | بريد | 141.09 لنا | 1.394 لنا | 2.108 لنا | 2.0000 | 1.5000 | - | 12440 ب |
أقوياء | SingleFromquery | بريد | 141.17 لنا | 1.941 لنا | 2.935 لنا | 1.7500 | 1.5000 | - | 12201 ب |
جَسِيم | "استعلام (ديناميكي)" | متحرك | 142.01 لنا | 4.957 لنا | 7.494 لنا | 2.0000 | 1.5000 | - | 12342 ب |
LINQ إلى DB | "الأول (المترجم)" | بريد | 144.59 لنا | 1.295 لنا | 1.958 لنا | 1.7500 | 1.5000 | - | 12128 ب |
repoDB | Queryfield | بريد | 148.31 لنا | 1.742 لنا | 2.633 لنا | 2.0000 | 1.5000 | 0.5000 | 13938 ب |
المعتاد | "اقرأ <> (tuples)" | Valuetuple`8 | 148.58 لنا | 2.172 لنا | 3.283 لنا | 2.0000 | 1.7500 | - | 12745 ب |
المعتاد | "اقرأ <()> (اسمه tuples)" | Valuetuple`8 | 150.60 لنا | 0.658 الولايات المتحدة | 1.106 لنا | 2.2500 | 2.0000 | 1.2500 | 14562 ب |
repoDB | استفسار | بريد | 152.34 الولايات المتحدة | 2.164 لنا | 3.271 لنا | 2.2500 | 1.5000 | 0.2500 | 14106 ب |
repoDB | QueryDynamic | بريد | 154.15 لنا | 4.108 لنا | 6.210 لنا | 2.2500 | 1.7500 | 0.5000 | 13930 ب |
repoDB | الاستعلام في أي مكان | بريد | 155.90 لنا | 1.953 لنا | 3.282 لنا | 2.5000 | 0.5000 | - | 14858 ب |
تأثير ذاكرة التخزين المؤقت Dapper | ExecuteNoparameters_Nocache | فارغ | 162.35 لنا | 1.584 لنا | 2.394 لنا | - | - | - | 760 ب |
تأثير ذاكرة التخزين المؤقت Dapper | ExecuteNoparameters_Cache | فارغ | 162.42 لنا | 2.740 لنا | 4.142 لنا | - | - | - | 760 ب |
تأثير ذاكرة التخزين المؤقت Dapper | QueryFirstNoparameters_Cache | فارغ | 164.35 لنا | 1.206 لنا | 1.824 لنا | 0.2500 | - | - | 1520 ب |
devexpress.xpo | FindObject | بريد | 165.87 لنا | 1.012 لنا | 1.934 لنا | 8.5000 | - | - | 28099 ب |
تأثير ذاكرة التخزين المؤقت Dapper | QueryFirstNoparameters_Nocache | فارغ | 173.87 لنا | 1.178 لنا | 1.781 لنا | 0.5000 | - | - | 1576 ب |
LINQ إلى DB | أولاً | بريد | 175.21 لنا | 2.292 لنا | 3.851 لنا | 2.0000 | 0.5000 | - | 14041 ب |
EF 6 | sqlquery | بريد | 175.36 لنا | 2.259 لنا | 3.415 لنا | 4.0000 | 0.7500 | - | 24209 ب |
المعتاد | "اقرأ <> (الفصل)" | بريد | 186.37 لنا | 1.305 لنا | 2.496 لنا | 3.0000 | 0.5000 | - | 17579 ب |
devexpress.xpo | getObjectBykey | بريد | 186.78 لنا | 3.407 لنا | 5.151 لنا | 4.5000 | 1.0000 | - | 30114 ب |
Dapper | 'استعلام (غير محصور)' ' | متحرك | 194.62 لنا | 1.335 لنا | 2.019 لنا | 1.7500 | 1.5000 | - | 12048 ب |
Dapper | 'استعلام (غير محصور)' ' | بريد | 195.01 لنا | 0.888 الولايات المتحدة | 1.343 لنا | 2.0000 | 1.5000 | - | 12008 ب |
devexpress.xpo | استفسار | بريد | 199.46 الولايات المتحدة | 5.500 الولايات المتحدة | 9.243 لنا | 10.0000 | - | - | 32083 ب |
بلغراد | FirstorDefault | Task`1 | 228.70 لنا | 2.181 لنا | 3.665 لنا | 4.5000 | 0.5000 | - | 20555 ب |
EF Core | "الأول (المترجم)" | بريد | 265.45 لنا | 17.745 لنا | 26.828 لنا | 2.0000 | - | - | 7521 ب |
nhibernate | يحصل | بريد | 276.02 لنا | 8.029 لنا | 12.139 لنا | 6.5000 | 1.0000 | - | 29885 ب |
nhibernate | HQL | بريد | 277.74 الولايات المتحدة | 13.032 لنا | 19.703 لنا | 8.0000 | 1.0000 | - | 31886 ب |
nhibernate | معايير | بريد | 300.22 الولايات المتحدة | 14.908 لنا | 28.504 لنا | 13.0000 | 1.0000 | - | 57562 ب |
EF 6 | أولاً | بريد | 310.55 لنا | 27.254 لنا | 45.799 لنا | 13.0000 | - | - | 43309 ب |
EF Core | أولاً | بريد | 317.12 لنا | 1.354 لنا | 2.046 لنا | 3.5000 | - | - | 11306 ب |
EF Core | sqlquery | بريد | 322.34 الولايات المتحدة | 23.990 لنا | 40.314 لنا | 5.0000 | - | - | 18195 ب |
nhibernate | SQL | بريد | 325.54 الولايات المتحدة | 3.937 لنا | 7.527 لنا | 22.0000 | 1.0000 | - | 80007 ب |
EF 6 | "الأول (لا تتبع)" | بريد | 331.14 لنا | 27.760 لنا | 46.649 لنا | 12.0000 | 1.0000 | - | 50237 ب |
EF Core | "الأول (لا تتبع)" | بريد | 337.82 لنا | 27.814 لنا | 46.740 لنا | 3.0000 | 1.0000 | - | 17986 ب |
nhibernate | LINQ | بريد | 604.74 لنا | 5.549 لنا | 10.610 لنا | 10.0000 | - | - | 46061 ب |
تأثير ذاكرة التخزين المؤقت Dapper | executeParameters_Nocache | فارغ | 623.42 لنا | 3.978 لنا | 6.684 لنا | 3.0000 | 2.0000 | - | 10001 ب |
تأثير ذاكرة التخزين المؤقت Dapper | queryfirstparameters_nocache | فارغ | 630.77 لنا | 3.027 لنا | 4.576 لنا | 3.0000 | 2.0000 | - | 10640 ب |
لا تتردد في تقديم تصحيحات تشمل OrMs الأخرى - عند تشغيل المعايير ، تأكد من تجميعها في الإصدار وعدم إرفاق مصحح تصحيح ( CTRL + F5 ).
بدلاً من ذلك ، قد تفضل جناح اختبار RawDataAccessBencher من Frans Bouma أو Ormbenchmark.
عادة ما يتم تمرير المعلمات كطبقات مجهولة. يتيح لك ذلك تسمية المعلمات الخاصة بك بسهولة ويمنحك القدرة على قطع مقتطفات SQL ببساطة وتشغيلها في محلل استعلام نظام DB الخاص بك.
new { A = 1 , B = " b " } // A will be mapped to the param @A, B to the param @B
يمكن أيضًا بناء المعلمات ديناميكيًا باستخدام فئة DynamicParameters. هذا يسمح ببناء بيان SQL ديناميكي مع الاستمرار في استخدام معلمات للسلامة والأداء.
var sqlPredicates = new List < string > ( ) ;
var queryParams = new DynamicParameters ( ) ;
if ( boolExpression )
{
sqlPredicates . Add ( " column1 = @param1 " ) ;
queryParams . Add ( " param1 " , dynamicValue1 , System . Data . DbType . Guid ) ;
} else {
sqlPredicates . Add ( " column2 = @param2 " ) ;
queryParams . Add ( " param2 " , dynamicValue2 , System . Data . DbType . String ) ;
}
تدعم DynamicParameters أيضًا نسخ معلمات متعددة من الكائنات الموجودة من أنواع مختلفة.
var queryParams = new DynamicParameters ( objectOfType1 ) ;
queryParams . AddDynamicParams ( objectOfType2 ) ;
عندما يتم تمرير كائن يقوم بتطبيق واجهة IDynamicParameters
في وظائف Execute
أو Query
، سيتم استخراج قيم المعلمة عبر هذه الواجهة. من الواضح أن فئة الكائن الأكثر ترجيحًا التي يجب استخدامها لهذا الغرض هي فئة DynamicParameters
المدمجة.
يتيح لك Dapper المرور في IEnumerable<int>
وسيقوم تلقائيًا بتطوير استعلامك.
على سبيل المثال:
connection . Query < int > ( " select * from (select 1 as Id union all select 2 union all select 3) as X where Id in @Ids " , new { Ids = new int [ ] { 1 , 2 , 3 } } ) ;
سيتم ترجمة إلى:
select * from ( select 1 as Id union all select 2 union all select 3 ) as X where Id in ( @Ids1 , @Ids2 , @Ids3 ) " // @Ids1 = 1 , @Ids2 = 2 , @Ids2 = 3
يدعم Dapper البدائل الحرفية للأنواع المنسوبة والرقم.
connection . Query ( " select * from User where UserTypeId = {=Admin} " , new { UserTypeId . Admin } ) ;
لا يتم إرسال الاستبدال الحرفي كمعلمة. يتيح ذلك خططًا أفضل واستخدام الفهرس المصفى ولكن يجب استخدامه عادةً بشكل ضئيل وبعد الاختبار. تكون هذه الميزة مفيدة بشكل خاص عندما تكون القيمة التي يتم حقنها هي في الواقع قيمة ثابتة (على سبيل المثال ، "معرف الفئة" أو "رمز الحالة" أو "المنطقة" خاصة بالاستعلام). بالنسبة للبيانات الحية التي تفكر فيها ، قد ترغب أيضًا في التفكير في تلميحات الاستعلام الخاصة بالمزود واختبارها مثل OPTIMIZE FOR UNKNOWN
مع المعلمات العادية.
السلوك الافتراضي لـ Dapper هو تنفيذ SQL الخاص بك ومخزن القارئ بأكمله عند العودة. هذا مثالي في معظم الحالات لأنه يقلل من الأقفال المشتركة في DB ويقلل من وقت شبكة DB.
ومع ذلك ، عند تنفيذ استعلامات ضخمة ، قد تحتاج إلى تقليل بصمة الذاكرة وتحميل الكائنات فقط حسب الحاجة. للقيام بذلك ، buffered: false
في طريقة Query
.
يتيح لك Dapper تعيين صف واحد لكائنات متعددة. هذه ميزة رئيسية إذا كنت ترغب في تجنب جمعيات التحميل الغريبة والاستعلام.
مثال:
ضع في اعتبارك فئتين: Post
and User
class Post
{
public int Id { get ; set ; }
public string Title { get ; set ; }
public string Content { get ; set ; }
public User Owner { get ; set ; }
}
class User
{
public int Id { get ; set ; }
public string Name { get ; set ; }
}
الآن دعنا نقول أننا نريد أن نرسم استعلامًا ينضم إلى كل من المشاركات وجدول المستخدمين. حتى الآن إذا كنا بحاجة إلى الجمع بين نتيجة استفسارين ، سنحتاج إلى كائن جديد للتعبير عنه ولكنه أكثر منطقية في هذه الحالة لوضع كائن User
داخل كائن Post
.
هذه هي حالة الاستخدام لرسم الخرائط المتعددة. أنت تخبر Dapper أن الاستعلام يرجع Post
وكائنًا User
ثم يعطيه وظيفة تصف ما تريد القيام به مع كل صف من الصفوف التي تحتوي على كل من Post
وكائن User
. في حالتنا ، نريد أن نأخذ كائن المستخدم ونضعه داخل كائن البريد. لذلك نكتب الوظيفة:
( post , user ) => { post . Owner = user ; return post ; }
تحدد الوسائط المكونة من 3 نوعًا إلى طريقة Query
ما الذي يجب أن تستخدمه الكائنات لتجاهل الصف وما سيتم إرجاعه. سنقوم بتفسير كلا الصفين على أنه مزيج من Post
User
، ونحن نعيد كائنًا Post
. وبالتالي يصبح إعلان النوع
< Post , User , Post >
كل شيء تم تجميعه معًا ، يبدو هكذا:
var sql =
@"select * from #Posts p
left join #Users u on u.Id = p.OwnerId
Order by p.Id" ;
var data = connection . Query < Post , User , Post > ( sql , ( post , user ) => { post . Owner = user ; return post ; } ) ;
var post = data . First ( ) ;
Assert . Equal ( " Sams Post1 " , post . Content ) ;
Assert . Equal ( 1 , post . Id ) ;
Assert . Equal ( " Sam " , post . Owner . Name ) ;
Assert . Equal ( 99 , post . Owner . Id ) ;
Dapper قادر على تقسيم الصف الذي تم إرجاعه عن طريق افتراض أن أعمدة المعرف الخاصة بك تسمية Id
أو id
. إذا كان المفتاح الأساسي الخاص بك مختلفًا أو ترغب في تقسيم الصف في نقطة أخرى غير Id
، فاستخدم معلمة splitOn
الاختيارية.
يتيح لك Dapper معالجة شبكات نتائج متعددة في استعلام واحد.
مثال:
var sql =
@"
select * from Customers where CustomerId = @id
select * from Orders where CustomerId = @id
select * from Returns where CustomerId = @id" ;
using ( var multi = connection . QueryMultiple ( sql , new { id = selectedId } ) )
{
var customer = multi . Read < Customer > ( ) . Single ( ) ;
var orders = multi . Read < Order > ( ) . ToList ( ) ;
var returns = multi . Read < Return > ( ) . ToList ( ) ;
.. .
}
يدعم Dapper بالكامل بروكس المخزنة:
var user = cnn . Query < User > ( " spGetUser " , new { Id = 1 } ,
commandType : CommandType . StoredProcedure ) . SingleOrDefault ( ) ;
إذا كنت تريد شيئًا أكثر خيالية ، فيمكنك القيام به:
var p = new DynamicParameters ( ) ;
p . Add ( " @a " , 11 ) ;
p . Add ( " @b " , dbType : DbType . Int32 , direction : ParameterDirection . Output ) ;
p . Add ( " @c " , dbType : DbType . Int32 , direction : ParameterDirection . ReturnValue ) ;
cnn . Execute ( " spMagicProc " , p , commandType : CommandType . StoredProcedure ) ;
int b = p . Get < int > ( " @b " ) ;
int c = p . Get < int > ( " @c " ) ;
يدعم Dapper params varchar ، إذا كنت تنفذ شرطًا على عمود varchar باستخدام param تأكد من تمريره بهذه الطريقة:
Query < Thing > ( " select * from Thing where Name = @Name " , new { Name = new DbString { Value = " abcde " , IsFixedLength = true , Length = 10 , IsAnsi = true } } ) ;
على SQL Server ، من الأهمية بمكان استخدام Unicode عند الاستعلام عن Unicode و ANSI عند الاستعلام عن غير Unicode.
عادةً ما ترغب في التعامل مع جميع الصفوف من جدول معين مثل نفس نوع البيانات. ومع ذلك ، هناك بعض الظروف حيث يكون من المفيد أن تكون قادرًا على تحليل صفوف مختلفة كنوع بيانات مختلفة. هذا هو المكان الذي يأتي فيه IDataReader.GetRowParser
.
تخيل أن لديك جدول قاعدة بيانات يسمى "الأشكال" مع الأعمدة: Id
، Type
، Data
، وتريد تحليل صفوفه في كائنات Circle
أو Square
أو Triangle
بناءً على قيمة عمود النوع.
var shapes = new List < IShape > ( ) ;
using ( var reader = connection . ExecuteReader ( " select * from Shapes " ) )
{
// Generate a row parser for each type you expect.
// The generic type <IShape> is what the parser will return.
// The argument (typeof(*)) is the concrete type to parse.
var circleParser = reader . GetRowParser < IShape > ( typeof ( Circle ) ) ;
var squareParser = reader . GetRowParser < IShape > ( typeof ( Square ) ) ;
var triangleParser = reader . GetRowParser < IShape > ( typeof ( Triangle ) ) ;
var typeColumnIndex = reader . GetOrdinal ( " Type " ) ;
while ( reader . Read ( ) )
{
IShape shape ;
var type = ( ShapeType ) reader . GetInt32 ( typeColumnIndex ) ;
switch ( type )
{
case ShapeType . Circle :
shape = circleParser ( reader ) ;
break ;
case ShapeType . Square :
shape = squareParser ( reader ) ;
break ;
case ShapeType . Triangle :
shape = triangleParser ( reader ) ;
break ;
default :
throw new NotImplementedException ( ) ;
}
shapes . Add ( shape ) ;
}
}
من أجل استخدام متغيرات SQL غير المعلمة مع موصل MySQL ، يجب عليك إضافة الخيار التالي إلى سلسلة الاتصال الخاصة بك:
Allow User Variables=True
تأكد من عدم تزويد Dapper بخاصية لرسم خريطة.
Dapper Caches معلومات حول كل استعلام يتم تشغيله ، وهذا يسمح لها بتحقيق الكائنات بسرعة ومعالجة المعلمات بسرعة. التنفيذ الحالي يخبؤ هذه المعلومات في كائن ConcurrentDictionary
. البيانات التي يتم استخدامها مرة واحدة فقط يتم مسحها بشكل روتيني من هذه ذاكرة التخزين المؤقت. ومع ذلك ، إذا كنت تقوم بإنشاء سلاسل SQL أثناء الطيران دون استخدام المعلمات ، فمن الممكن أن تضغط على مشكلات الذاكرة.
تعني بساطة Dapper أن العديد من الميزات التي تشحنها معها يتم تجريدها. إنه يقلق من سيناريو 95 ٪ ، ويمنحك الأدوات التي تحتاجها معظم الوقت. لا تحاول حل كل مشكلة.
لا يوجد لدى Dapper تفاصيل تنفيذ محددة DB ، وهو يعمل في جميع مزودي ADO .NET بما في ذلك SQLITE و SQL CE و FIREBIRD و ORACLE و MARIADB و MYSQL و POSTGRESQL و SQL.
لدى Dapper مجموعة اختبار شاملة في مشروع الاختبار.
يتم استخدام Dapper في الإنتاج في Scack Overflow.