پیاده سازی جستجو بدون دستورات If پیچیده درMVC

یکشنبه 5 اردیبهشت 1395

برای کسانی که شروع به یادگیری #C و MVC میکنند ، ایجاد فرم جستجو پیچیده است. درباره اینترفیس IQueryable اطلاعی ندارند و اینکه اجراهای به تعویق افتاده در linq چگونه کار میکند. در این مقاله نحوه ایجاد هر نوع از فرم جستجو را بدون این پیچیدگیها با استفاده از اجراهای به تعویق افتاده Linq نشان خواهیم داد.

پیاده سازی جستجو بدون دستورات  If پیچیده درMVC

برای کسانی که شروع به یادگیری #C و  MVC میکنند ، ایجاد فرم جستجو پیچیده است. درباره اینترفیس IQueryable اطلاعی ندارند و اینکه اجراهای به تعویق افتاده در linq چگونه کار میکند. در این مقاله نحوه ایجاد هر نوع از فرم جستجو را بدون این پیچیدگیها با استفاده از اجراهای به تعویق افتاده Linq نشان خواهیم داد.

راه اشتباه برای ایجاد فرم جستجو

در اینجا کدهای نامناسب این فرم را مشاهده میکنید :

public ActionResult ManageOrders
(DateTime fromDate, DateTime toDate, string tracingCode, string customerName)
        {
            if (!string.IsNullOrEmpty(fromDate) && !string.IsNullOrEmpty(toDate) 
            && string.IsNullOrEmpty(tracingCode) && string.IsNullOrEmpty(customerName))
            {
                var model = db.Orders.Where(s => s.OrderDate >= fromDate && s.OrderDate <= toDate);
                return View(model);
            }
            else if (!string.IsNullOrEmpty(fromDate) && !string.IsNullOrEmpty(toDate) 
            && !string.IsNullOrEmpty(tracingCode) && !string.IsNullOrEmpty(customerName))
            {
                var model = db.Orders.Where(s => s.OrderDate >= fromDate 
                && s.OrderDate <= toDate 
                && s.TracingCode == tracingCode && s.CustomerName == customerName);
                return View(model);
            }
            else if (!string.IsNullOrEmpty(fromDate) && !string.IsNullOrEmpty(toDate) 
            && string.IsNullOrEmpty(tracingCode) && !string.IsNullOrEmpty(customerName))
            {
                var model = db.Orders.Where(s => s.OrderDate >= fromDate 
                && s.OrderDate <= toDate && s.CustomerName == customerName);
                return View(model);
            }
            else if (!string.IsNullOrEmpty(fromDate) && !string.IsNullOrEmpty(toDate) 
            && !string.IsNullOrEmpty(tracingCode) && string.IsNullOrEmpty(customerName))
            {
                var model = db.Orders.Where(s => s.OrderDate >= fromDate 
                && s.OrderDate <= toDate && s.TracingCode == tracingCode);
                return View(model);
            }
            else if (string.IsNullOrEmpty(fromDate) && string.IsNullOrEmpty(toDate) 
            && !string.IsNullOrEmpty(tracingCode) && !string.IsNullOrEmpty(customerName))
            {
                var model = db.Orders.Where(s => s.TracingCode == tracingCode 
                && s.CustomerName == customerName);
                return View(model);
            }
            else if (string.IsNullOrEmpty(fromDate) && string.IsNullOrEmpty(toDate) 
            && string.IsNullOrEmpty(tracingCode) && !string.IsNullOrEmpty(customerName))
            {
                var model = db.Orders.Where(s => s.CustomerName == customerName);
                return View(model);
            }
            else if (string.IsNullOrEmpty(fromDate) && string.IsNullOrEmpty(toDate) 
            && !string.IsNullOrEmpty(tracingCode) && string.IsNullOrEmpty(customerName))
            {
                var model = db.Orders.Where(s => s.TracingCode == tracingCode);
                return View(model);
            }

            return View(db.Orders);            
	    }

همانطور که میبینید باید هر یک از شرط ها چک میشد برای زمانی که یک فیلد پر شده و دیگری خالی است و بالعکس، و مدل فیلتر مناسبی را بازگرداند. این روش نامناسب است و نباید استفاده شود. 

راه مناسب برای ایجاد فرم جستجو

با قدرتی که Linq و اجراهای به تعویق افتاده آن به ما می دهند، کد بالا را به صورت زیر تغییر می دهیم.

public ActionResult ManageOrders
(DateTime fromDate, DateTime toDate, string tracingCode, string customerName)
        {
            IQueryable<orders> orders = db.Orders;

            if (!string.IsNullOrEmpty(fromDate) && !string.IsNullOrEmpty(toDate))
            {
                orders = orders.Where(s => s.OrderDate >= startDate && s.OrderDate <= endDate);
            }

            if (!string.IsNullOrEmpty(tracingCode))
            {
                orders = orders.Where(s => s.TracingCode.Contains(tracingCode));
            }

            if (!string.IsNullOrEmpty(customerName))
            {
                orders = orders.Where(s => s.CustomerName.Contains(customerName));
            }
			
            return View(orders);
	    }</orders>

حتی می توانید این کد را نیز با  Ifهای سه تایی کوتاه تر کنید ، اما نکته این است که تمام کاری که باید انجام دهیم چک کردن پارامتر action است که خالی نباشد و یک where دیگر نیز به کوئری جستجو اضافه کنیم.  در اینجا از  Linq به SQL استفاده شده است که با  Linq به Object یا شی متفاوت است ، ما از Linq به Object هم می توانیم استفاده کنیم ، به عبارت دیگر از IEnumerable بجای IQueryable استفاده کنیم،  در اینجا استفاده از  IQueryable کارامدتر است.  Linq به SQL ، کوئری های ما را در SQL Server اجرا میکند ، پس تنها چیزی که نیاز داریم را دریافت میکنیم. اما  Linq به Object تمام موجودیت ها را بازیابی کرده و در حافظه فیلتر میکند.

 با اجرای تعویق افتاده که  Linq به ما می دهد ، می توانیم  IQueryable  یا IEnumerable ایجاد کنیم و  Whereهای خود را بر روی آن بر اساس شرایط موجود جمع آوری کنیم که خیلی بهتر از ان است که قبلا انجام دادیم .

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید