समस्या यह प्रतीत होती है कि आपको गलतफहमी हो गई है कि एंटिटी फ्रेमवर्क के साथ कैसे काम करता है।
एंटिटी फ्रेमवर्क के बारे में
तो, आइए इस कोड को देखें:
public IQueryable<URL> GetAllUrls()
{
return context.Urls.AsQueryable();
}
और इसके उपयोग का उदाहरण:
repo.GetAllUrls().Where(u => <condition>).Take(10).ToList()
वहां क्या होता है?
- हम
IQueryable
ऑब्जेक्ट (अभी तक डेटाबेस तक नहीं पहुंच) का उपयोग कर रहे हैंrepo.GetAllUrls()
- हम
IQueryable
निर्दिष्ट स्थिति का उपयोग करके एक नई वस्तु बनाते हैं.Where(u => <condition>
- हम
IQueryable
उपयोग करके निर्दिष्ट पेजिंग सीमा के साथ एक नई वस्तु बनाते हैं.Take(10)
- हम डेटाबेस का उपयोग करके परिणाम प्राप्त करते हैं
.ToList()
। हमारी IQueryable
वस्तु sql (जैसे select top 10 * from Urls where <condition>
) संकलित है । और डेटाबेस अनुक्रमित का उपयोग कर सकता है, sql सर्वर आपको आपके डेटाबेस से केवल 10 ऑब्जेक्ट भेजता है (डेटाबेस में संग्रहीत सभी अरब यूआरएल नहीं)
ठीक है, पहले कोड को देखें:
public async Task<IQueryable<URL>> GetAllUrlsAsync()
{
var urls = await context.Urls.ToListAsync();
return urls.AsQueryable();
}
उपयोग के समान उदाहरण के साथ हमें मिला:
- हम आपके डेटाबेस में उपयोग किए गए सभी अरब url को मेमोरी में लोड कर रहे हैं
await context.Urls.ToListAsync();
।
- हमें मेमोरी ओवरफ्लो हो गई। अपने सर्वर को मारने का सही तरीका
Async / प्रतीक्षा के बारे में
क्यों async / प्रतीक्षा का उपयोग करने के लिए पसंद किया जाता है? आइए इस कोड को देखें:
var stuff1 = repo.GetStuff1ForUser(userId);
var stuff2 = repo.GetStuff2ForUser(userId);
return View(new Model(stuff1, stuff2));
यहाँ क्या हुआ?
- लाइन 1 पर शुरू
var stuff1 = ...
- हम sql सर्वर को अनुरोध भेजते हैं कि हम कुछ सामान प्राप्त करना चाहते हैं
userId
- हम प्रतीक्षा करते हैं (वर्तमान थ्रेड अवरुद्ध है)
- हम प्रतीक्षा करते हैं (वर्तमान थ्रेड अवरुद्ध है)
- .....
- Sql सर्वर हमें प्रतिक्रिया भेजें
- हम पंक्ति 2 में जाते हैं
var stuff2 = ...
- हम sql सर्वर को अनुरोध भेजते हैं कि हम कुछ सामान प्राप्त करना चाहते हैं
userId
- हम प्रतीक्षा करते हैं (वर्तमान थ्रेड अवरुद्ध है)
- और फिर
- .....
- Sql सर्वर हमें प्रतिक्रिया भेजें
- हम दृश्य प्रस्तुत करते हैं
तो चलिए इसके एक async संस्करण को देखते हैं:
var stuff1Task = repo.GetStuff1ForUserAsync(userId);
var stuff2Task = repo.GetStuff2ForUserAsync(userId);
await Task.WhenAll(stuff1Task, stuff2Task);
return View(new Model(stuff1Task.Result, stuff2Task.Result));
यहाँ क्या हुआ?
- हम sql सर्वर को stuff1 प्राप्त करने के लिए अनुरोध भेजते हैं (पंक्ति 1)
- हम sql सर्वर को stuff2 प्राप्त करने के लिए अनुरोध भेजते हैं (पंक्ति 2)
- हम sql सर्वर से प्रतिक्रियाओं की प्रतीक्षा करते हैं, लेकिन वर्तमान थ्रेड अवरुद्ध नहीं है, वह अन्य उपयोगकर्ताओं के प्रश्नों को संभाल सकता है
- हम दृश्य प्रस्तुत करते हैं
इसे करने का सही तरीका
तो यहाँ अच्छा कोड:
using System.Data.Entity;
public IQueryable<URL> GetAllUrls()
{
return context.Urls.AsQueryable();
}
public async Task<List<URL>> GetAllUrlsByUser(int userId) {
return await GetAllUrls().Where(u => u.User.Id == userId).ToListAsync();
}
ध्यान दें, IQueryable के लिए using System.Data.Entity
विधि का उपयोग करने के ToListAsync()
लिए आपको जोड़ना चाहिए ।
ध्यान दें, यदि आपको फ़िल्टरिंग और पेजिंग और सामान की आवश्यकता नहीं है, तो आपको काम करने की आवश्यकता नहीं है IQueryable
। आप केवल await context.Urls.ToListAsync()
भौतिकता के साथ उपयोग और काम कर सकते हैं List<Url>
।