खोज…


वाक्य - विन्यास

  • public static IEnumerable<TReturn> Query<TFirst, TSecond, TReturn>( this IDbConnection cnn, string sql, Func<TFirst, TSecond, TReturn> map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null)
  • public static IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn> map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null)
  • public static IEnumerable<TReturn> Query<TReturn>(this IDbConnection cnn, string sql, Type[] types, Func<object[], TReturn> map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null)

पैरामीटर

पैरामीटर विवरण
सीएनएन आपका डेटाबेस कनेक्शन, जो पहले से ही खुला होना चाहिए।
एसक्यूएल निष्पादित करने की आज्ञा।
प्रकार रिकॉर्ड सेट में प्रकारों की सरणी।
नक्शा Func<> जो रिटर्न परिणाम के निर्माण को संभालता है।
परम से पैरामीटर निकालने के लिए वस्तु।
लेन-देन लेन-देन जो इस क्वेरी का एक हिस्सा है, यदि कोई हो।
बफर क्वेरी के परिणामों को पढ़ने के लिए बफर करना है या नहीं। यह डिफ़ॉल्ट होने के साथ एक वैकल्पिक पैरामीटर सत्य है। जब बफ़र्ड सही होता है, तो परिणाम एक List<T> में बफ़र किए जाते हैं और फिर एक IEnumerable<T> रूप में लौटाया जाता है जो कई गणन के लिए सुरक्षित है। जब बफ़र झूठा होता है, तब तक sql कनेक्शन खुला रखा जाता है जब तक कि आप रीडिंग खत्म नहीं कर देते हैं, जिससे आप मेमोरी में एक ही पंक्ति को संसाधित कर सकते हैं। एकाधिक गणना डेटाबेस के लिए अतिरिक्त कनेक्शन स्पॉन करेगा। जबकि बफ़र किए गए झूठे स्मृति उपयोग को कम करने के लिए अत्यधिक कुशल हैं यदि आप केवल रिकॉर्ड के बहुत छोटे टुकड़े बनाए रखते हैं, तो इसके परिणामस्वरूप परिणाम सेट करने की तुलना में एक उल्लेखनीय प्रदर्शन ओवरहेड होता है । अंत में यदि आपके पास कई समवर्ती असंबद्ध वर्गीय कनेक्शन हैं, तो आपको कनेक्शन पूल भुखमरी पर विचार करने की आवश्यकता है जब तक कि कनेक्शन उपलब्ध न हो जाए।
पर विभाजित वह फ़ील्ड जिसे हमें (डिफ़ॉल्ट: आईडी) से दूसरी ऑब्जेक्ट को विभाजित और पढ़ना चाहिए। यह एक अल्पविराम सीमांकित सूची हो सकती है जब एक रिकॉर्ड में 1 से अधिक प्रकार निहित होता है।
CommandTimeout कमांड निष्पादन समय से पहले सेकंड की संख्या।
commandType यह एक संग्रहित खरीद या एक बैच है?

सरल मल्टी-टेबल मैपिंग

मान लीजिए कि हमारे पास शेष घुड़सवारों की एक क्वेरी है जिन्हें एक व्यक्ति वर्ग को आबाद करने की आवश्यकता है।

नाम उत्पन्न होने वाली रहने का स्थान
डैनियल डेनेट 1942 संयुक्त राज्य अमरीका
सैम हैरिस 1967 संयुक्त राज्य अमरीका
रिचर्ड डॉकिन्स 1941 यूनाइटेड किंगडम
public class Person
{
    public string Name { get; set; }
    public int Born { get; set; }
    public Country Residience { get; set; }
}

public class Country
{
    public string Residence { get; set; }
}

हम एक अधिभार Query<> का उपयोग कर देश के एक उदाहरण के साथ व्यक्ति वर्ग के साथ-साथ निवास संपत्ति को पॉपुलेट कर सकते हैं Query<> जो एक Func<> लेता है जिसका उपयोग लौटा हुआ उदाहरण लिखने के लिए किया जा सकता है। Func<> अंतिम जेनेरिक तर्क के साथ 7 इनपुट प्रकार ले सकता है हमेशा रिटर्न प्रकार।

var sql = @"SELECT 'Daniel Dennett' AS Name, 1942 AS Born, 'United States of America' AS Residence
UNION ALL SELECT 'Sam Harris' AS Name, 1967 AS Born, 'United States of America' AS Residence
UNION ALL SELECT 'Richard Dawkins' AS Name, 1941 AS Born, 'United Kingdom' AS Residence";

var result = connection.Query<Person, Country, Person>(sql, (person, country) => {
        if(country == null)
        {
            country = new Country { Residence = "" };
        }
        person.Residience = country;
        return person;
    }, 
    splitOn: "Residence");

splitOn: "Residence" के उपयोग पर ध्यान दें splitOn: "Residence" तर्क जो कि आबादी वाले (इस मामले में Country ) अगली श्रेणी के प्रकार का 1 कॉलम है। डैपर स्वचालित रूप से ईद नामक एक कॉलम को विभाजित करने के लिए देखेगा, लेकिन यदि यह एक नहीं मिलता है और splitOn प्रदान नहीं किया जाता है तो एक System.ArgumentException को एक उपयोगी संदेश के साथ फेंक दिया जाएगा। इसलिए यद्यपि यह वैकल्पिक है, आपको आमतौर पर एक splitOn मान की आपूर्ति करनी होगी।

एक से कई मानचित्रण

आइए एक अधिक जटिल उदाहरण देखें जिसमें एक-से-कई संबंध हैं। हमारी क्वेरी में अब डुप्लिकेट डेटा वाली कई पंक्तियाँ होंगी और हमें इसे संभालना होगा। हम इसे एक क्लोजर में देखने के साथ करते हैं।

उदाहरण वर्ग के रूप में क्वेरी थोड़ा बदलता है।

ईद नाम उत्पन्न होने वाली countryID देश का नाम BookId BookName
1 डैनियल डेनेट 1942 1 संयुक्त राज्य अमरीका 1 brainstorms
1 डैनियल डेनेट 1942 1 संयुक्त राज्य अमरीका 2 हाथ रखने की जगह
2 सैम हैरिस 1967 1 संयुक्त राज्य अमरीका 3 मोरल लैंडस्केप
2 सैम हैरिस 1967 1 संयुक्त राज्य अमरीका 4 जागने: धर्म के बिना आध्यात्मिकता के लिए एक गाइड
3 रिचर्ड डॉकिन्स 1941 2 यूनाइटेड किंगडम 5 हकीकत का जादू: हम कैसे जानते हैं कि क्या सच है
3 रिचर्ड डॉकिन्स 1941 2 यूनाइटेड किंगडम 6 एक भूख के लिए आश्चर्य: एक वैज्ञानिक का निर्माण
public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Born { get; set; }
    public Country Residience { get; set; }
    public ICollection<Book> Books { get; set; }
}

public class Country
{
    public int CountryId { get; set; }
    public string CountryName { get; set; }
}

public class Book
{
    public int BookId { get; set; }
    public string BookName { get; set; }
}

शब्दकोश remainingHorsemen व्यक्ति वस्तुओं के पूरी तरह से भौतिक उदाहरणों के साथ आबादी वाले होंगे। क्वेरी की प्रत्येक पंक्ति के परिणाम के लिए लंबो तर्कों में दिए गए प्रकारों के उदाहरणों के मैप किए गए मान पास किए गए हैं और यह आप पर निर्भर है कि इसे कैसे संभालना है।

            var sql = @"SELECT 1 AS Id, 'Daniel Dennett' AS Name, 1942 AS Born, 1 AS CountryId, 'United States of America' AS CountryName, 1 AS BookId, 'Brainstorms' AS BookName
UNION ALL SELECT 1 AS Id, 'Daniel Dennett' AS Name, 1942 AS Born, 1 AS CountryId, 'United States of America' AS CountryName, 2 AS BookId, 'Elbow Room' AS BookName
UNION ALL SELECT 2 AS Id, 'Sam Harris' AS Name, 1967 AS Born, 1 AS CountryId,  'United States of America' AS CountryName, 3 AS BookId, 'The Moral Landscape' AS BookName
UNION ALL SELECT 2 AS Id, 'Sam Harris' AS Name, 1967 AS Born, 1 AS CountryId,  'United States of America' AS CountryName, 4 AS BookId, 'Waking Up: A Guide to Spirituality Without Religion' AS BookName
UNION ALL SELECT 3 AS Id, 'Richard Dawkins' AS Name, 1941 AS Born, 2 AS CountryId,  'United Kingdom' AS CountryName, 5 AS BookId, 'The Magic of Reality: How We Know What`s Really True' AS BookName
UNION ALL SELECT 3 AS Id, 'Richard Dawkins' AS Name, 1941 AS Born, 2 AS CountryId,  'United Kingdom' AS CountryName, 6 AS BookId, 'An Appetite for Wonder: The Making of a Scientist' AS BookName";

var remainingHorsemen = new Dictionary<int, Person>();
connection.Query<Person, Country, Book, Person>(sql, (person, country, book) => {
    //person
    Person personEntity;
    //trip
    if (!remainingHorsemen.TryGetValue(person.Id, out personEntity))
    {
        remainingHorsemen.Add(person.Id, personEntity = person);
    }

    //country
    if(personEntity.Residience == null)
    {
        if (country == null)
        {
            country = new Country { CountryName = "" };
        }
        personEntity.Residience = country;
    }                    

    //books
    if(personEntity.Books == null)
    {
        personEntity.Books = new List<Book>();
    }

    if (book != null)
    {
        if (!personEntity.Books.Any(x => x.BookId == book.BookId))
        {
            personEntity.Books.Add(book);
        }
    }

    return personEntity;
}, 
splitOn: "CountryId,BookId");

ध्यान दें कि splitOn तर्क अगले प्रकार के पहले कॉलम की कॉमा सीमांकित सूची है।

7 से अधिक प्रकार की मैपिंग

कभी-कभी आपके द्वारा मैप किए जाने वाले प्रकारों की संख्या फंक <> द्वारा प्रदान की गई 7 से अधिक होती है जो निर्माण करती है।

सामान्य प्रकार के तर्क इनपुट के साथ Query<> का उपयोग करने के बजाय, हम मैपिंग फ़ंक्शन के बाद सरणी के रूप में मैप करने के लिए प्रकार प्रदान करेंगे। मूल्यों की प्रारंभिक मैनुअल सेटिंग और कास्टिंग के अलावा, बाकी फ़ंक्शन नहीं बदलता है।

            var sql = @"SELECT 1 AS Id, 'Daniel Dennett' AS Name, 1942 AS Born, 1 AS CountryId, 'United States of America' AS CountryName, 1 AS BookId, 'Brainstorms' AS BookName
UNION ALL SELECT 1 AS Id, 'Daniel Dennett' AS Name, 1942 AS Born, 1 AS CountryId, 'United States of America' AS CountryName, 2 AS BookId, 'Elbow Room' AS BookName
UNION ALL SELECT 2 AS Id, 'Sam Harris' AS Name, 1967 AS Born, 1 AS CountryId,  'United States of America' AS CountryName, 3 AS BookId, 'The Moral Landscape' AS BookName
UNION ALL SELECT 2 AS Id, 'Sam Harris' AS Name, 1967 AS Born, 1 AS CountryId,  'United States of America' AS CountryName, 4 AS BookId, 'Waking Up: A Guide to Spirituality Without Religion' AS BookName
UNION ALL SELECT 3 AS Id, 'Richard Dawkins' AS Name, 1941 AS Born, 2 AS CountryId,  'United Kingdom' AS CountryName, 5 AS BookId, 'The Magic of Reality: How We Know What`s Really True' AS BookName
UNION ALL SELECT 3 AS Id, 'Richard Dawkins' AS Name, 1941 AS Born, 2 AS CountryId,  'United Kingdom' AS CountryName, 6 AS BookId, 'An Appetite for Wonder: The Making of a Scientist' AS BookName";

var remainingHorsemen = new Dictionary<int, Person>();
connection.Query<Person>(sql,
    new[]
    {
        typeof(Person),
        typeof(Country),
        typeof(Book)
    }
    , obj => {

        Person person = obj[0] as Person;
        Country country = obj[1] as Country;
        Book book = obj[2] as Book;

        //person
        Person personEntity;
        //trip
        if (!remainingHorsemen.TryGetValue(person.Id, out personEntity))
        {
            remainingHorsemen.Add(person.Id, personEntity = person);
        }

        //country
        if(personEntity.Residience == null)
        {
            if (country == null)
            {
                country = new Country { CountryName = "" };
            }
            personEntity.Residience = country;
        }                    

        //books
        if(personEntity.Books == null)
        {
            personEntity.Books = new List<Book>();
        }

        if (book != null)
        {
            if (!personEntity.Books.Any(x => x.BookId == book.BookId))
            {
                personEntity.Books.Add(book);
            }
        }

        return personEntity;
},
splitOn: "CountryId,BookId");

कस्टम मैपिंग

यदि क्वेरी कॉलम नाम आपकी कक्षाओं से मेल नहीं खाते हैं तो आप प्रकारों के लिए मैपिंग सेटअप कर सकते हैं। यह उदाहरण System.Data.Linq.Mapping.ColumnAttribute साथ-साथ एक कस्टम मैपिंग का System.Data.Linq.Mapping.ColumnAttribute करके मैपिंग प्रदर्शित करता है।

मैपिंग को केवल एक बार सेटअप करने की आवश्यकता होती है, इसलिए उन्हें एप्लिकेशन स्टार्टअप या कहीं और सेट करें ताकि वे केवल एक बार आरंभिक हों।

एक ही क्वेरी को एक से कई उदाहरणों के रूप में फिर से मानते हुए और वर्गों को इस तरह से बेहतर नामों की ओर दर्शाया गया है:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Born { get; set; }
    public Country Residience { get; set; }
    public ICollection<Book> Books { get; set; }
}

public class Country
{
    [System.Data.Linq.Mapping.Column(Name = "CountryId")]
    public int Id { get; set; }

    [System.Data.Linq.Mapping.Column(Name = "CountryName")]
    public string Name { get; set; }
}

public class Book
{
    public int Id { get; set; }

    public string Name { get; set; }
}

ध्यान दें कि कैसे Book ColumnAttribute पर निर्भर नहीं करती है, लेकिन हमें if कथन को बनाए रखने की आवश्यकता होगी

अब इस मैपिंग कोड को अपने आवेदन में कहीं पर रखें जहाँ इसे केवल एक बार निष्पादित किया गया हो:

Dapper.SqlMapper.SetTypeMap(
    typeof(Country),
    new CustomPropertyTypeMap(
        typeof(Country),
        (type, columnName) =>
            type.GetProperties().FirstOrDefault(prop =>
                prop.GetCustomAttributes(false)
                    .OfType<System.Data.Linq.Mapping.ColumnAttribute>()
                    .Any(attr => attr.Name == columnName)))
);


var bookMap = new CustomPropertyTypeMap(
    typeof(Book),
    (type, columnName) =>
    {
        if(columnName == "BookId")
        {
            return type.GetProperty("Id");
        }

        if (columnName == "BookName")
        {
            return type.GetProperty("Name");
        }

        throw new InvalidOperationException($"No matching mapping for {columnName}");
    }        
);
Dapper.SqlMapper.SetTypeMap(typeof(Book), bookMap);

फिर क्वेरी को किसी भी पिछले Query<> उदाहरणों का उपयोग करके निष्पादित किया जाता है।

मैपिंग को जोड़ने का एक सरल तरीका इस उत्तर में दिखाया गया है।



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