PDA

View Full Version : نحوه Async کردن متد Get/GetAll با خروجی IQueryable در ریپوزیتوری :



ehsan_kabiri_33
دوشنبه 19 خرداد 1399, 14:45 عصر
سلام
درود. در صورتیکه متد Get ما بازگشتی از نوع IQueryable داشته باشد (به دلیل واکشی مناسب اطلاعات از دیتا بیس) چگونه میتوان آنرا Async کرد؟؟





public IQueryable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, string includeProperties = null)
{
IQueryable<TEntity> query = _dbSet;
if (filter != null)
{
query = query.Where(filter);
}
if (orderBy != null)
{
query = orderBy(query);
}
if (includeProperties != null)
{
foreach (var includeProperty in includeProperties.Split(new Char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProperty);
}
}
return query;
}



چون برای Async شدن باید به .ToListAsync تبدیل شود که در آن صورت دیگر Iqueryable نخواهد بود و کل دیتا از دیتا بیس فراخوانی میشود. و در صورت عدم استفاده از Tolist نمیدونم چطوری میشه درخواستهای Get را به صورت Async اجرا کرد.

ali_md110
دوشنبه 19 خرداد 1399, 17:47 عصر
به هیچ دلیل مورد نیاز نیست که یک IQueryable تبدیل به صورت یک Async باشد
چون هیچ درخواستی به سرور ندارد
تبدییل به متد های Async هنگامی است که بخواهیم یک درخواست ارسال کنیم یا یک پردازش یا درخواستی به دیتابیس صورت گیرد

ehsan_kabiri_33
سه شنبه 20 خرداد 1399, 08:22 صبح
درود. ممنون که جواب دادید.

راستش حرفتون را درست نمیفهمم.
مثلا ما موقع Add کردن اون را به AddAsync تبدیل میکنیم. قابل فهمه
اما IQueryable در مرحله اول درون Repository خب هیچ درخواستی به سرور ندارد ، درست. اما بعدش که من توی یک کنترولر اون را صدا میزنم مانند زیر :

public async Task<IActionResult> Index() {
IEnumerable<Product> productList =_unitOfWork.productRepository.Get();
return View();


}


الان این درخواست داره اطلاعات را واکشی میکنه دیگه، آیا این کار/ درخواست حساب نمیشه که بشه اون را به صورت Async انجام داد؟؟ یعنی نیازی نیست من هیچ کاری انجام بدم؟؟

ali_md110
پنج شنبه 22 خرداد 1399, 00:35 صبح
ببینید دوست من IQueryable فقط یک عبارت هست و تا زمانیکه به tolist تبدیل نشود به سمت دیتابیس واکشی ندارد
هیچ وقت متدهاتون از نوع IQueryable نسازید مانند مثال خودتون , چون نشتی دارند و به leaky abstraction معروف هستند . یعنی اینکه انتهای آن بسته نشده و باز هست و به راحتی میتوان از روی آن به سایر جداول دیگر دسترسی داشت.
IQueryable را فقط درون متدی بکار ببرید که انتهایش به ToList یا ToListAsync ختم شود تا تبدیل به SQL شده و سپس بر روی بانک اطلاعاتی اجرا شود.
البته این متد خودتون رو میتونید درون یک متدی دیگر بجز IActionResult که در معرض کاربر هست استفاده کنید
پس نتیجه این شد که ازمتدی که ToListAsync داشته باشه در ActionResult استفاده کنید نه یک IQueryable خام و قابل تحریف و یا هک