সমস্যাটি দেখে মনে হচ্ছে আপনি সত্তা ফ্রেমওয়ার্কের সাথে কীভাবে async / কাজের প্রতীক্ষা করছেন তা ভুল বুঝেছেন।
সত্তা ফ্রেমওয়ার্ক সম্পর্কে
সুতরাং, আসুন এই কোডটি দেখুন:
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
অবজেক্টটি স্কয়ারে (যেমন select top 10 * from Urls where <condition>
) সংকলিত হয় । এবং ডাটাবেস সূচীগুলি ব্যবহার করতে পারে, এসকিউএল সার্ভার আপনাকে আপনার ডাটাবেস থেকে কেবলমাত্র 10 টি বস্তু প্রেরণ করবে (ডাটাবেসে থাকা সমস্ত বিলিয়ন ইউআরএল নয়)
ঠিক আছে, আসুন প্রথম কোডটি দেখুন:
public async Task<IQueryable<URL>> GetAllUrlsAsync()
{
var urls = await context.Urls.ToListAsync();
return urls.AsQueryable();
}
ব্যবহারের একই উদাহরণ সহ আমরা পেয়েছি:
- আমরা আপনার ডাটাবেসে সঞ্চিত সমস্ত বিলিয়ন ইউআরএল মেমরিতে লোড করছি
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 = ...
- আমরা স্কয়ার সার্ভারে অনুরোধটি প্রেরণ করি যা আমরা কিছু স্টাফ 1 পেতে চাই
userId
- আমরা অপেক্ষা করি (বর্তমান থ্রেড অবরুদ্ধ)
- আমরা অপেক্ষা করি (বর্তমান থ্রেড অবরুদ্ধ)
- .....
- SQL সার্ভার আমাদের প্রতিক্রিয়া প্রেরণ
- আমরা লাইন 2 এ চলেছি
var stuff2 = ...
- আমরা স্কিএল সার্ভারে অনুরোধটি প্রেরণ করি যা আমরা কিছু স্টাফ 2 পেতে চাই
userId
- আমরা অপেক্ষা করি (বর্তমান থ্রেড অবরুদ্ধ)
- এবং আবার
- .....
- SQL সার্ভার আমাদের প্রতিক্রিয়া প্রেরণ
- আমরা ভিউ রেন্ডার করি
সুতরাং আসুন এটির একটি অ্যাসিঙ্ক সংস্করণটি দেখুন:
var stuff1Task = repo.GetStuff1ForUserAsync(userId);
var stuff2Task = repo.GetStuff2ForUserAsync(userId);
await Task.WhenAll(stuff1Task, stuff2Task);
return View(new Model(stuff1Task.Result, stuff2Task.Result));
এখানে কি হয়?
- স্টাফ 1 (লাইন 1) পাওয়ার জন্য আমরা এসকিএল সার্ভারে অনুরোধ পাঠাব
- স্টাফ 2 (লাইন 2) পাওয়ার জন্য আমরা এসকিএল সার্ভারে অনুরোধটি প্রেরণ করি
- আমরা স্কিএল সার্ভারের প্রতিক্রিয়াগুলির জন্য অপেক্ষা করি, তবে বর্তমান থ্রেডটি অবরুদ্ধ নয়, তিনি অন্য ব্যবহারকারীদের কাছ থেকে প্রশ্নগুলি পরিচালনা করতে পারেন
- আমরা ভিউ রেন্ডার করি
এটি করার সঠিক উপায়
এখানে খুব ভাল কোড:
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();
}
দ্রষ্টব্য, আইকিউয়েরেবলের জন্য using System.Data.Entity
পদ্ধতিটি ব্যবহার করার জন্য আপনাকে অবশ্যই যুক্ত করতে হবে ToListAsync()
।
দ্রষ্টব্য, আপনার যদি ফিল্টারিং এবং পেজিং এবং স্টাফের প্রয়োজন না হয় তবে আপনার সাথে কাজ করার দরকার নেই IQueryable
। আপনি কেবল ব্যবহার await context.Urls.ToListAsync()
এবং উপাদানযুক্ত সঙ্গে কাজ করতে পারেন List<Url>
।