खोज…


पैरामीटर

पैरामीटर विवरण
this cnn अंतर्निहित डेटाबेस कनेक्शन - this एक विस्तार विधि को दर्शाता है; कनेक्शन को खोलने की आवश्यकता नहीं है - यदि यह खुला नहीं है, तो इसे स्वचालित रूप से खोला और बंद किया जाता है।
<T> / Type (वैकल्पिक) लौटने के लिए वस्तु का प्रकार; यदि गैर-जेनेरिक / गैर- Type API का उपयोग किया जाता है, तो प्रति पंक्ति एक dynamic ऑब्जेक्ट को प्रति पंक्ति में लौटाया जाता है, जो प्रति कॉलम नाम की एक प्रॉपर्टी को क्वेरी से IDicionary<string,object> (यह dynamic ऑब्जेक्ट IDicionary<string,object> ) को लागू करता है।
sql निष्पादित करने के लिए एसक्यूएल
param (वैकल्पिक) शामिल करने के लिए पैरामीटर।
transaction (वैकल्पिक) डेटाबेस लेनदेन कमांड के साथ जुड़ने के लिए
buffered (वैकल्पिक) डेटा को सूची (डिफ़ॉल्ट) में पूर्व-उपभोग करना है, या लाइव रीडर पर एक खुला IEnumerable को उजागर करना
commandTimeout (वैकल्पिक) कमांड पर उपयोग करने का समय समाप्त; यदि निर्दिष्ट नहीं है, SqlMapper.Settings.CommandTimeout मान लिया गया है (यदि निर्दिष्ट किया गया है)
commandType जिस प्रकार की आज्ञा दी जा रही है; CommandText चूक

टिप्पणियों

मापदंडों को व्यक्त करने का सिंटैक्स RDBMS के बीच भिन्न होता है। उपरोक्त सभी उदाहरण SQL सर्वर सिंटैक्स का उपयोग करते हैं, अर्थात @foo ; हालांकि, ?foo और :foo भी ठीक काम करना चाहिए।

बेसिक Parameterized SQL

डैपर पूरी तरह से मानकीकृत एसक्यूएल के माध्यम से सर्वोत्तम अभ्यास का पालन करना आसान बनाता है।

बॉबी टेबल्स

पैरामीटर महत्वपूर्ण हैं, इसलिए डैपर इसे सही तरीके से प्राप्त करना आसान बनाता है। आप बस अपने RDBMS (आमतौर पर @foo ; ?foo या :foo ) के लिए सामान्य तरीके से अपने मापदंडों को व्यक्त करते हैं और डैपर को एक वस्तु देते हैं जिसमें एक सदस्य होता है जिसे foo कहते हैं । ऐसा करने का सबसे आम तरीका एक अनाम प्रकार है:

int id = 123;
string name = "abc";
connection.Execute("insert [KeyLookup](Id, Name) values(@id, @name)",
    new { id, name });

और बस। डैपर आवश्यक पैरामीटर जोड़ देगा और सब कुछ काम करना चाहिए।

अपने ऑब्जेक्ट मॉडल का उपयोग करना

आप अपने मौजूदा ऑब्जेक्ट मॉडल को एक पैरामीटर के रूप में भी उपयोग कर सकते हैं:

KeyLookup lookup = ... // some existing instance
connection.Execute("insert [KeyLookup](Id, Name) values(@Id, @Name)", lookup);

साफ-सुथरी जो वस्तु के सदस्यों को जोड़ने की निर्धारित करने के लिए आदेश-पाठ का उपयोग करता है - यह आमतौर पर की तरह अनावश्यक चीजों को नहीं जोड़ेगा Description , IsActive , CreationDate क्योंकि आदेश हम स्पष्ट रूप से जारी किए गए हैं उन्हें शामिल नहीं करता है - हालांकि ऐसे मामले हैं जब यह कर रहे हैं उदाहरण के लिए, यदि आपकी कमांड में ऐसा हो सकता है:

// TODO - removed for now; include the @Description in the insert

यह पता लगाने की कोशिश नहीं की जाती है कि उपरोक्त केवल एक टिप्पणी है।

संग्रहित प्रक्रियाएं

संग्रहीत प्रक्रियाओं के पैरामीटर ठीक उसी तरह काम करते हैं, सिवाय इसके कि डपर यह निर्धारित करने का प्रयास नहीं कर सकता कि क्या होना चाहिए / शामिल नहीं होना चाहिए - उपलब्ध हर चीज को एक पैरामीटर के रूप में माना जाता है। इस कारण से, अनाम प्रकार आमतौर पर पसंद किए जाते हैं:

connection.Execute("KeyLookupInsert", new { id, name },
    commandType: CommandType.StoredProcedure);

वैल्यू इनलाइनिंग

कभी-कभी एक पैरामीटर के रूप में इलाज के लिए एक पैरामीटर की सुविधा (रखरखाव और अभिव्यक्ति के संदर्भ में), प्रदर्शन में इसकी लागत से आगे निकल सकती है। उदाहरण के लिए, जब पृष्ठ आकार एक विन्यास सेटिंग द्वारा तय किया जाता है। या कोई स्थिति मूल्य एक करने के लिए मिलान किया जाता है enum मूल्य। विचार करें:

var orders = connection.Query<Order>(@"
select top (@count) * -- these brackets are an oddity of SQL Server
from Orders
where CustomerId = @customerId
and Status = @open", new { customerId, count = PageSize, open = OrderStatus.Open });

यहाँ केवल वास्तविक पैरामीटर customerId - अन्य दो छद्म पैरामीटर हैं जो वास्तव में नहीं बदलेंगे। अक्सर आरडीबीएमएस एक बेहतर काम कर सकता है यदि यह उन्हें स्थिरांक के रूप में पहचानता है। डैपर के पास इसके लिए एक विशेष वाक्यविन्यास है - {=name} बजाय @name - जो केवल संख्यात्मक प्रकारों पर लागू होता है। (यह SQL इंजेक्शन से किसी भी हमले की सतह को कम करता है)। एक उदाहरण इस प्रकार है:

var orders = connection.Query<Order>(@"
select top {=count} *
from Orders
where CustomerId = @customerId
and Status = {=open}", new { customerId, count = PageSize, open = OrderStatus.Open });

Dapper SQL जारी करने से पहले शाब्दिक के साथ मूल्यों की जगह लेता है, इसलिए RDBMS वास्तव में कुछ इस तरह देखता है:

select top 10 *
from Orders
where CustomerId = @customerId
and Status = 3

यह विशेष रूप से तब उपयोगी होता है जब RDBMS सिस्टम को न केवल बेहतर निर्णय लेने की अनुमति होती है, बल्कि वास्तविक मापदंडों को रोकने वाली क्वेरी योजनाओं को खोलने के लिए भी। उदाहरण के लिए, यदि कोई कॉलम किसी पैरामीटर के विरुद्ध है, तो उस कॉलम पर विशिष्ट मान वाले फ़िल्टर किए गए इंडेक्स का उपयोग नहीं किया जा सकता है। ऐसा इसलिए है क्योंकि अगली क्वेरी में उन निर्दिष्ट मानों में से एक के अलावा एक पैरामीटर हो सकता है।

शाब्दिक मूल्यों के साथ, क्वेरी ऑप्टिमाइज़र फ़िल्टर्ड इंडेक्स का उपयोग करने में सक्षम है क्योंकि यह जानता है कि भविष्य के प्रश्नों में मूल्य बदल नहीं सकता है।

सूची विस्तार

डेटाबेस क्वेरीज़ में एक सामान्य परिदृश्य IN (...) जहां रनटाइम पर यहां सूची तैयार की जाती है। अधिकांश RDBMS में इसके लिए एक अच्छा रूपक का अभाव है - और इसके लिए कोई सार्वभौमिक क्रॉस-RDBMS समाधान नहीं है। इसके बजाय, डैपर कुछ कोमल स्वचालित कमांड विस्तार प्रदान करता है। सभी की आवश्यकता है कि एक आपूर्ति पैरामीटर मान है जो IEnumerable@foo से संबंधित कमांड का विस्तार (@foo0,@foo1,@foo2,@foo3) (4 आइटम के अनुक्रम के लिए) के लिए किया गया है। इसका सबसे आम उपयोग IN होगा:

int[] orderIds = ...
var orders = connection.Query<Order>(@"
select *
from Orders
where Id in @orderIds", new { orderIds });

इसके बाद बहु-पंक्ति लाने के लिए स्वचालित रूप से उपयुक्त SQL जारी करने का विस्तार होता है:

select *
from Orders
where Id in (@orderIds0, @orderIds1, @orderIds2, @orderIds3)

पैरामीटर के साथ @orderIds0 आदि को ऐरे से लिए गए मानों के रूप में जोड़ा जा रहा है। ध्यान दें कि यह मान्य SQL मूल रूप से मान्य नहीं है, यह सुनिश्चित करने के लिए कि यह सुविधा गलती से उपयोग नहीं की गई है। यह सुविधा SQL सर्वर में OPTIMIZE FOR / UNKNOWN क्वेरी-हिंट के साथ भी सही ढंग से काम करती है; यदि तुम प्रयोग करते हो:

option (optimize for
    (@orderIds unknown))

यह इसका सही तरीके से विस्तार करेगा:

option (optimize for
    (@orderIds0 unknown, @orderIds1 unknown, @orderIds2 unknown, @orderIds3 unknown))

इनपुट के कई सेटों के खिलाफ ऑपरेशन करना

कभी-कभी, आप एक ही काम को कई बार करना चाहते हैं। साफ-सुथरी पर इस का समर्थन करता है Execute विधि अगर सबसे बाहरी पैरामीटर (जो आमतौर पर एक भी गुमनाम प्रकार है, या एक डोमेन मॉडल उदाहरण) वास्तव में एक के रूप में प्रदान की जाती है IEnumerable अनुक्रम। उदाहरण के लिए:

Order[] orders = ...
// update the totals
connection.Execute("update Orders set Total=@Total where Id=@Id", orders);

यहाँ, डैपर हमारे डेटा पर एक साधारण लूप कर रहा है, अनिवार्य रूप से वैसा ही जैसा कि हमने किया था:

Order[] orders = ...
// update the totals
foreach(Order order in orders) {
    connection.Execute("update Orders set Total=@Total where Id=@Id", order);
}

यह उपयोग विशेष रूप से दिलचस्प हो जाता है जब एक कनेक्शन पर async एपीआई के साथ संयुक्त रूप से सभी "एकाधिक सक्रिय परिणाम सेट" में स्पष्ट रूप से कॉन्फ़िगर किया गया है - इस उपयोग में, डैपर स्वचालित रूप से संचालन को पाइप करेगा, इसलिए आप प्रति पंक्ति विलंबता लागत का भुगतान नहीं कर रहे हैं। इसके लिए थोड़ा और अधिक जटिल उपयोग की आवश्यकता है,

await connection.ExecuteAsync(
    new CommandDefinition(
        "update Orders set Total=@Total where Id=@Id", 
         orders, flags: CommandFlags.Pipelined))

हालाँकि, ध्यान दें, कि आप तालिका के मूल्यवान मापदंडों की जाँच करना चाहते हैं।

छद्म-स्थितिगत पैरामीटर (उन प्रदाताओं के लिए जो नामित मापदंडों का समर्थन नहीं करते हैं)

कुछ ADO.NET प्रदाता (सबसे विशेष रूप से: OleDB) नामित मापदंडों का समर्थन नहीं करते हैं; मापदंडों को केवल स्थिति के अनुसार निर्दिष्ट किया जाता है, के साथ ? जगह-धारक। डैपर को यह पता नहीं होगा कि किस सदस्य को इनका उपयोग करना है, इसलिए डैपर एक वैकल्पिक वाक्यविन्यास की अनुमति देता है ?foo? ; यह अन्य SQL वेरिएंट में @foo या :foo जैसा ही होगा, सिवाय इसके कि डैपर पैरामीटर टोकन को पूरी तरह से बदल देगा ? क्वेरी निष्पादित करने से पहले।

यह सूची विस्तार जैसे अन्य विशेषताओं के साथ काम करता है, इसलिए निम्न मान्य है:

string region = "North";
int[] users = ...
var docs = conn.Query<Document>(@"
     select * from Documents
     where Region = ?region?
     and OwnerId in ?users?", new { region, users }).AsList();

.region और .users सदस्यों का उपयोग तदनुसार किया जाता है, और जारी किया गया SQL (उदाहरण के लिए, 3 उपयोगकर्ताओं के साथ) है:

     select * from Documents
     where Region = ?
     and OwnerId in (?,?,?)

ध्यान दें, हालाँकि, इस सुविधा का उपयोग करते समय एक ही पैरामीटर को कई बार उपयोग करने की अनुमति नहीं देता है; यह एक ही पैरामीटर मान (जो बड़ा हो सकता है) को कई बार जोड़ने से रोकने के लिए है। यदि आपको कई बार एक ही मूल्य को संदर्भित करने की आवश्यकता है, तो उदाहरण के लिए एक चर घोषित करने पर विचार करें:

declare @id int = ?id?; // now we can use @id multiple times in the SQL

यदि चर उपलब्ध नहीं हैं, तो आप मापदंडों में डुप्लिकेट सदस्य नामों का उपयोग कर सकते हैं - इससे यह भी स्पष्ट हो जाएगा कि मूल्य कई बार भेजा जा रहा है:

int id = 42;
connection.Execute("... where ParentId = $id0$ ... SomethingElse = $id1$ ...",
      new { id0 = id, id1 = id });


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow