{"id":1122,"date":"2019-07-13T23:46:14","date_gmt":"2019-07-13T20:46:14","guid":{"rendered":"https:\/\/enisnecipoglu.com\/?p=1122"},"modified":"2019-07-13T23:49:26","modified_gmt":"2019-07-13T20:49:26","slug":"auto-filtering-in-aspnetcore","status":"publish","type":"post","link":"https:\/\/enisnecipoglu.com\/en\/auto-filtering-in-aspnetcore\/","title":{"rendered":"Auto Filtering in AspNetCore"},"content":{"rendered":"<h2>Summary<\/h2>\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n<p>Today, I&#8217;m presenting to you, automatic filterin in AspNetCore Web Applications. That basicly converts Query String to LINQ without writing any of code, isn&#8217;t it amazing? Let&#8217;s follow this paper to understand that:<\/p>\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n<h2>Problem<\/h2>\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n<p>Let&#8217;s understand what is the problem and what will be automated. Think about you have a Blog entity like below:<\/p>\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n<pre class=\"wp-block-code\">\n\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"text codecolorer\">public class Blog<br \/>\n{<br \/>\n&nbsp; &nbsp; public string BlogId { get; set; }<br \/>\n&nbsp; &nbsp; public int CategoryId { get; set; }<br \/>\n&nbsp; &nbsp; public int Priority { get; set; }<br \/>\n&nbsp; &nbsp; public bool IsPublished { get; set; }<br \/>\n&nbsp; &nbsp; public DateTime PublishDate { get; set; }<br \/>\n}<\/div><\/div>\n\n<\/pre>\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n<p>And think about you have a DTO to filter Blogs:<\/p>\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n<pre class=\"wp-block-code\">\n\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"text codecolorer\">public class BlogFilterDto <br \/>\n{<br \/>\n&nbsp; &nbsp; public int CategoryId { get; set; }<br \/>\n&nbsp; &nbsp; public int Priority { get; set; }<br \/>\n&nbsp; &nbsp; public bool? IsPublished { get; set; }<br \/>\n&nbsp; &nbsp; public DateTime PublishDate { get; set; }<br \/>\n}<\/div><\/div>\n\n<\/pre>\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n<p>Now, this dto parameters comes from QueryString and it is used to filter Blogs in Controller via classical way:<\/p>\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n<pre class=\"wp-block-code\">\n\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;height:300px;\"><div class=\"text codecolorer\">&nbsp; &nbsp; [Route(&quot;api\/[controller]&quot;)]<br \/>\n&nbsp; &nbsp; [ApiController]<br \/>\n&nbsp; &nbsp; public class BlogsController : ControllerBase<br \/>\n&nbsp; &nbsp; {<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; [HttpGet]<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; public async Task&amp;lt;IActionResult&amp;gt; Get([FromQuery]BlogFilterDto filter)<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; {<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var db = new MyDbContext();<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var query = db.Blogs;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (filter.CategoryId != null)<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; query = query.Where(x =&amp;gt; x.CategoryId == filter.CategoryId);<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (filter.IsPublished != null)<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; query = query.Where(x =&amp;gt; x.IsPublished == filter.IsPublished);<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (filter.Priority != null)<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; query = query.Where(x =&amp;gt; x.Priority == filter.Priority);<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (filter.PublishDate != null)<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; query = query.Where(x =&amp;gt; x.PublishDate == filter.PublishDate);<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var list = query.ToList();<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return Ok(list);<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; }<br \/>\n&nbsp; &nbsp; }<\/div><\/div>\n\n<\/pre>\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n<p>Uhh, it is too much painful and compicated codes and stuffs.<\/p>\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n<h2>Solution<\/h2>\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n<p>There is a lot of way to solve this problem like reflection but the main point is keep conversion to dabase queries ability. That means we need to generate expressions from properties. It&#8217;s not logically right, to do this for each model. That&#8217;s why I created a library that converts properties to Expressions that can be applied on Entity Framework IQuaryable. That is <a href=\"https:\/\/github.com\/enisn\/AutoFilterer\">AutoFilterer<\/a><\/p>\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n<h3>AutoFilterer<\/h3>\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n<p>Firstly, add <strong>AutoFilterer<\/strong> to your project from NuGet. You can visit <a href=\"https:\/\/github.com\/enisn\/AutoFilterer\/wiki\">wiki page<\/a> to read more detailed installation and usage documentations.<\/p>\r\n\r\n<p>&nbsp;<\/p>\r\n<hr class=\"wp-block-separator\" \/>\r\n<p>&nbsp;<\/p>\r\n\r\n<p>Afterall, go your DTO and inherit from FilterBase class.<\/p>\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n<pre class=\"wp-block-code\">\n\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"text codecolorer\">public class BlogFilterDto : FilterBase&amp;lt;Blog&amp;gt;<br \/>\n{<br \/>\n&nbsp; &nbsp; public int CategoryId { get; set; }<br \/>\n&nbsp; &nbsp; public int Priority { get; set; }<br \/>\n&nbsp; &nbsp; public bool? IsPublished { get; set; }<br \/>\n&nbsp; &nbsp; public DateTime PublishDate { get; set; }<br \/>\n}<\/div><\/div>\n\n<\/pre>\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n<p>And, go back to your controller and remove all the stuffs and just use <strong>ApplyFilterTo() <\/strong>method to generate expression and apply to DbSet. That&#8217;s it. It&#8217;s amazing, everything works easily with a clean controller code or repository code or whatever you say&#8230;<\/p>\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n<pre class=\"wp-block-code\">\n\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"text codecolorer\">&nbsp; &nbsp; [Route(&quot;api\/[controller]&quot;)]<br \/>\n&nbsp; &nbsp; [ApiController]<br \/>\n&nbsp; &nbsp; public class BlogsController : ControllerBase<br \/>\n&nbsp; &nbsp; {<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; \/\/ api\/Blogs<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; \/\/ api\/Blogs?categoryId=8<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; \/\/ api\/Blogs?categoryId=8&amp;amp;isPublished=False<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; \/\/ api\/Blogs?priority=2<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; [HttpGet]<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; public async Task&amp;lt;IActionResult&amp;gt; Get([FromQuery]BlogFilterDto filter)<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; {<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var db = new MyDbContext();<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var list = filter.ApplyFilterTo(db.Blogs).ToList();<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return Ok(list);<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; }<br \/>\n&nbsp; &nbsp; }<\/div><\/div>\n\n<\/pre>\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n<p><br \/>\u00a0Advanced configurations are made in your DTO with attributes. That keeps your code clean and readable with an amazing way! You can use this library in any platform, it&#8217;s for only Web API. You can use it in MVC projects with returning `View()` instead of `Ok()`<\/p>\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n<h3>Advaned Options<\/h3>\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n<p>For more feature, like Pagination, Range filtering, string search, you can find instructions from <a href=\"https:\/\/github.com\/enisn\/AutoFilterer\">GitHub Page<\/a><\/p>\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n<p>Bu i\u015flemi otomatize etmenin pek \u00e7ok yolu var. Fakat istedi\u011fimiz yol Expression \u00fcretmek ve do\u011frudan Entity Framework \u00fczerinden DB sorgusuna d\u00f6n\u00fc\u015febilmesini sa\u011flamak. Bunu her bir model i\u00e7in ayr\u0131 ayr\u0131 yapmak yerine, Generic bir \u015fekilde yapan bir k\u00fct\u00fcphane geli\u015ftirdim: <a href=\"https:\/\/github.com\/enisn\/AutoFilterer\">AutoFilterer<\/a><\/p>\r\n\r\n<h3>AutoFilterer<\/h3>\r\n\r\n<p>&nbsp;<\/p>\r\n<!-- wp:paragraph -->\r\n<p>Projemize <strong>AutoFilterer<\/strong> k\u00fct\u00fcphanesini <strong>NuGet Package<\/strong> olarak ekliyoruz. Daha detayl\u0131 kurulum ve kullan\u0131m talimatlar\u0131 i\u00e7in GitHub&#8217;daki <a href=\"https:\/\/github.com\/enisn\/AutoFilterer\/wiki\">wiki sayfas\u0131<\/a>n\u0131 ziyaret edebilirsiniz.<\/p>\r\n<!-- wp:separator --><hr class=\"wp-block-separator\" \/><!-- \/wp:separator -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:paragraph -->\r\n<p>Daha sonra DTO class&#8217;\u0131na gidip FilterBase objesinden miras almas\u0131n\u0131 sa\u011flay\u0131n<\/p>\r\n<!-- \/wp:paragraph -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:code -->\r\n<pre class=\"wp-block-code\">\n\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"text codecolorer\">public class BlogFilterDto : FilterBase&amp;lt;Blog&amp;gt;<br \/>\n{<br \/>\n&nbsp; &nbsp; public int CategoryId { get; set; }<br \/>\n&nbsp; &nbsp; public int Priority { get; set; }<br \/>\n&nbsp; &nbsp; public bool? IsPublished { get; set; }<br \/>\n&nbsp; &nbsp; public DateTime PublishDate { get; set; }<br \/>\n}<\/div><\/div>\n\n<\/pre>\r\n<!-- \/wp:code -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:paragraph -->\r\n<p>Ve sonunda Controller&#8217;a d\u00f6n\u00fcp b\u00fct\u00fcn o uzun hardcode edilmi\u015f k\u0131sm\u0131 temizleyip <strong>ApplyFilterTo()<\/strong> methodunu \u00e7a\u011f\u0131rabiliriz. Bu otomatik olarak Expression olu\u015fturup, DbSet&#8217;teki IQuaryable koleksiyona uygulam\u0131\u015f olacak. Daha sonras\u0131nda ile tek yapmam\u0131z gereken bu sorguyu \u00e7al\u0131\u015ft\u0131rmak.<\/p>\r\n<!-- \/wp:paragraph -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:shortcode \/-->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:code -->\r\n<pre class=\"wp-block-code\">\n\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"text codecolorer\">&nbsp; &nbsp; [Route(&quot;api\/[controller]&quot;)]<br \/>\n&nbsp; &nbsp; [ApiController]<br \/>\n&nbsp; &nbsp; public class BlogsController : ControllerBase<br \/>\n&nbsp; &nbsp; {<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; \/\/ api\/Blogs<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; \/\/ api\/Blogs?categoryId=8<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; \/\/ api\/Blogs?categoryId=8&amp;amp;isPublished=False<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; \/\/ api\/Blogs?priority=2<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; [HttpGet]<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; public async Task&amp;lt;IActionResult&amp;gt; Get([FromQuery]BlogFilterDto filter)<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; {<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var db = new MyDbContext();<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var list = filter.ApplyFilterTo(db.Blogs).ToList();<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return Ok(list);<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; }<br \/>\n&nbsp; &nbsp; }<\/div><\/div>\n\n<\/pre>\r\n<!-- \/wp:code -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:paragraph -->\r\n<p>B\u00f6ylelikle \u00e7ok daha temiz bir kod elde etmi\u015f olduk. Advanced d\u00fczey ayarlamalar\u0131 da DTO \u00fczerinden attribute&#8217;ler ile yapm\u0131\u015f olaca\u011f\u0131m\u0131zdan, filtreleme sorgular\u0131yla ilgili herhangi bir \u015fey kodun d\u00fczenini ve okunabilirli\u011fini bozmam\u0131\u015f olacak. Sadece Web API projelerinde de\u011fil, MVC projelerinde de kullan\u0131labilir. `Ok()` yerine `View()` return edip, view k\u0131sm\u0131nda filtrelenmi\u015f listeyi kullanabilirsiniz.\u00a0<\/p>\r\n<!-- \/wp:paragraph -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:heading {\"level\":3} -->\r\n<h3>\u0130leri D\u00fczey Ayarlamalar<\/h3>\r\n<!-- \/wp:heading -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:paragraph -->\r\n<p>Sayfalama, aral\u0131k filtreleme, string i\u00e7erisinde arama gibi \u00f6zellikler i\u00e7in <a href=\"https:\/\/github.com\/enisn\/AutoFilterer\">GitHub sayfas\u0131<\/a>ndaki talimatlar\u0131 takip edebilirsiniz.<\/p>\r\n<!-- \/wp:paragraph -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:paragraph -->\r\n<p>&nbsp;<\/p>\r\n<!-- \/wp:paragraph --><!-- wp:heading -->\r\n<h2>Summary<\/h2>\r\n<!-- \/wp:heading -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:paragraph -->\r\n<p>Today, I&#8217;m presenting to you, automatic filterin in AspNetCore Web Applications. That basicly converts Query String to LINQ without writing any of code, isn&#8217;t it amazing? Let&#8217;s follow this paper to understand that:<\/p>\r\n<!-- \/wp:paragraph -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:heading -->\r\n<h2>Problem<\/h2>\r\n<!-- \/wp:heading -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:paragraph -->\r\n<p>Let&#8217;s understand what is the problem and what will be automated. Think about you have a Blog entity like below:<\/p>\r\n<!-- \/wp:paragraph -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:code -->\r\n<pre class=\"wp-block-code\">\n\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"text codecolorer\">public class Blog<br \/>\n{<br \/>\n&nbsp; &nbsp; public string BlogId { get; set; }<br \/>\n&nbsp; &nbsp; public int CategoryId { get; set; }<br \/>\n&nbsp; &nbsp; public int Priority { get; set; }<br \/>\n&nbsp; &nbsp; public bool IsPublished { get; set; }<br \/>\n&nbsp; &nbsp; public DateTime PublishDate { get; set; }<br \/>\n}<\/div><\/div>\n\n<\/pre>\r\n<!-- \/wp:code -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:paragraph -->\r\n<p>And think about you have a DTO to filter Blogs:<\/p>\r\n<!-- \/wp:paragraph -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:code -->\r\n<pre class=\"wp-block-code\">\n\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"text codecolorer\">public class BlogFilterDto <br \/>\n{<br \/>\n&nbsp; &nbsp; public int CategoryId { get; set; }<br \/>\n&nbsp; &nbsp; public int Priority { get; set; }<br \/>\n&nbsp; &nbsp; public bool? IsPublished { get; set; }<br \/>\n&nbsp; &nbsp; public DateTime PublishDate { get; set; }<br \/>\n}<\/div><\/div>\n\n<\/pre>\r\n<!-- \/wp:code -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:paragraph -->\r\n<p>Now, this dto parameters comes from QueryString and it is used to filter Blogs in Controller via classical way:<\/p>\r\n<!-- \/wp:paragraph -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:code -->\r\n<pre class=\"wp-block-code\">\n\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;height:300px;\"><div class=\"text codecolorer\">&nbsp; &nbsp; [Route(&quot;api\/[controller]&quot;)]<br \/>\n&nbsp; &nbsp; [ApiController]<br \/>\n&nbsp; &nbsp; public class BlogsController : ControllerBase<br \/>\n&nbsp; &nbsp; {<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; [HttpGet]<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; public async Task&amp;lt;IActionResult&amp;gt; Get([FromQuery]BlogFilterDto filter)<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; {<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var db = new MyDbContext();<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var query = db.Blogs;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (filter.CategoryId != null)<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; query = query.Where(x =&amp;gt; x.CategoryId == filter.CategoryId);<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (filter.IsPublished != null)<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; query = query.Where(x =&amp;gt; x.IsPublished == filter.IsPublished);<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (filter.Priority != null)<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; query = query.Where(x =&amp;gt; x.Priority == filter.Priority);<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (filter.PublishDate != null)<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; query = query.Where(x =&amp;gt; x.PublishDate == filter.PublishDate);<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var list = query.ToList();<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return Ok(list);<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; }<br \/>\n&nbsp; &nbsp; }<\/div><\/div>\n\n<\/pre>\r\n<!-- \/wp:code -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:paragraph -->\r\n<p>Uhh, it is too much painful and compicated codes and stuffs.<\/p>\r\n<!-- \/wp:paragraph -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:heading -->\r\n<h2>Solution<\/h2>\r\n<!-- \/wp:heading -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:paragraph -->\r\n<p>There is a lot of way to solve this problem like reflection but the main point is keep conversion to dabase queries ability. That means we need to generate expressions from properties. It&#8217;s not logically right, to do this for each model. That&#8217;s why I created a library that converts properties to Expressions that can be applied on Entity Framework IQuaryable. That is <a href=\"https:\/\/github.com\/enisn\/AutoFilterer\">AutoFilterer<\/a><\/p>\r\n<!-- \/wp:paragraph -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:heading {\"level\":3} -->\r\n<h3>AutoFilterer<\/h3>\r\n<!-- \/wp:heading -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:paragraph -->\r\n<p>Firstly, add <strong>AutoFilterer<\/strong> to your project from NuGet. You can visit <a href=\"https:\/\/github.com\/enisn\/AutoFilterer\/wiki\">wiki page<\/a> to read more detailed installation and usage documentations.<\/p>\r\n<!-- \/wp:paragraph -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:separator --><hr class=\"wp-block-separator\" \/><!-- \/wp:separator -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:paragraph -->\r\n<p>Afterall, go your DTO and inherit from FilterBase class.<\/p>\r\n<!-- \/wp:paragraph -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:code -->\r\n<pre class=\"wp-block-code\">\n\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"text codecolorer\">public class BlogFilterDto : FilterBase&amp;lt;Blog&amp;gt;<br \/>\n{<br \/>\n&nbsp; &nbsp; public int CategoryId { get; set; }<br \/>\n&nbsp; &nbsp; public int Priority { get; set; }<br \/>\n&nbsp; &nbsp; public bool? IsPublished { get; set; }<br \/>\n&nbsp; &nbsp; public DateTime PublishDate { get; set; }<br \/>\n}<\/div><\/div>\n\n<\/pre>\r\n<!-- \/wp:code -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:paragraph -->\r\n<p>And, go back to your controller and remove all the stuffs and just use <strong>ApplyFilterTo() <\/strong>method to generate expression and apply to DbSet. That&#8217;s it. It&#8217;s amazing, everything works easily with a clean controller code or repository code or whatever you say&#8230;<\/p>\r\n<!-- \/wp:paragraph -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:shortcode \/-->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:code -->\r\n<pre class=\"wp-block-code\">\n\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"text codecolorer\">&nbsp; &nbsp; [Route(&quot;api\/[controller]&quot;)]<br \/>\n&nbsp; &nbsp; [ApiController]<br \/>\n&nbsp; &nbsp; public class BlogsController : ControllerBase<br \/>\n&nbsp; &nbsp; {<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; \/\/ api\/Blogs<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; \/\/ api\/Blogs?categoryId=8<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; \/\/ api\/Blogs?categoryId=8&amp;amp;isPublished=False<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; \/\/ api\/Blogs?priority=2<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; [HttpGet]<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; public async Task&amp;lt;IActionResult&amp;gt; Get([FromQuery]BlogFilterDto filter)<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; {<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var db = new MyDbContext();<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var list = filter.ApplyFilterTo(db.Blogs).ToList();<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return Ok(list);<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; }<br \/>\n&nbsp; &nbsp; }<\/div><\/div>\n\n<\/pre>\r\n<!-- \/wp:code -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:paragraph -->\r\n<p><br \/>\u00a0Advanced configurations are made in your DTO with attributes. That keeps your code clean and readable with an amazing way! You can use this library in any platform, it&#8217;s for only Web API. You can use it in MVC projects with returning `View()` instead of `Ok()`<\/p>\r\n<!-- \/wp:paragraph -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:heading {\"level\":3} -->\r\n<h3>Advaned Options<\/h3>\r\n<!-- \/wp:heading -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:paragraph -->\r\n<p>For more feature, like Pagination, Range filtering, string search, you can find instructions from <a href=\"https:\/\/github.com\/enisn\/AutoFilterer\">GitHub Page<\/a><\/p>\r\n<!-- \/wp:paragraph -->\r\n<p>&nbsp;<\/p>\r\n<!-- wp:paragraph -->\r\n<p>&nbsp;<\/p>\r\n<!-- \/wp:paragraph -->","protected":false},"excerpt":{"rendered":"Summary &nbsp; Today, I&#8217;m presenting to you, automatic filterin in AspNetCore Web Applications. That basicly converts Query String to LINQ without writing any of code, isn&#8217;t it amazing? Let&#8217;s follow this paper to understand that: &nbsp; Problem &nbsp; Let&#8217;s understand what is the problem and what will be automated. Think about you have a Blog entity like below: &nbsp; public class Blog { &nbsp; &nbsp; public string BlogId { get; set; } &nbsp; &nbsp; public int CategoryId { get; set; } &nbsp; &nbsp; public int Priority { get; set; } &nbsp; &nbsp; public bool IsPublished { get; set; } &nbsp; &nbsp; public DateTime PublishDate { get; set; } } &nbsp; And think about you have a DTO to filter Blogs: &nbsp; public class BlogFilterDto { &nbsp; &nbsp; public int CategoryId { get; set; } &nbsp; &nbsp; public int Priority { get; set; } &nbsp; &nbsp; public bool? IsPublished { get; set; } &nbsp; &nbsp; public DateTime PublishDate { get; set; } } &nbsp; Now, this dto parameters comes from QueryString and it is used to filter Blogs in Controller via classical way: &nbsp; &nbsp; &nbsp; &quot;)] &nbsp; &nbsp;  &nbsp; &nbsp; public class BlogsController : ControllerBase &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp; &nbsp;  &nbsp; &nbsp; &nbsp; &nbsp; public async Task&amp;lt;IActionResult&amp;gt; Get(BlogFilterDto filter) &nbsp; &nbsp; &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var db = new MyDbContext(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var query = db.Blogs; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (filter.CategoryId != null) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; query = query.Where(x =&amp;gt; x.CategoryId == filter.CategoryId); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (filter.IsPublished != null) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; query = query.Where(x =&amp;gt; x.IsPublished == filter.IsPublished); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (filter.Priority != null) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; query = query.Where(x =&amp;gt; x.Priority == filter.Priority); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (filter.PublishDate != null) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; query = query.Where(x =&amp;gt; x.PublishDate == filter.PublishDate); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var list = query.ToList(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return Ok(list); &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; } &nbsp; Uhh, it is too much painful and compicated codes and stuffs. &nbsp; Solution &nbsp; There is a lot of way to solve this problem like reflection but the main point is keep conversion to ","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[20,6],"tags":[68,67,71,73,72,69,70],"_links":{"self":[{"href":"https:\/\/enisnecipoglu.com\/en\/wp-json\/wp\/v2\/posts\/1122"}],"collection":[{"href":"https:\/\/enisnecipoglu.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/enisnecipoglu.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/enisnecipoglu.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/enisnecipoglu.com\/en\/wp-json\/wp\/v2\/comments?post=1122"}],"version-history":[{"count":11,"href":"https:\/\/enisnecipoglu.com\/en\/wp-json\/wp\/v2\/posts\/1122\/revisions"}],"predecessor-version":[{"id":1133,"href":"https:\/\/enisnecipoglu.com\/en\/wp-json\/wp\/v2\/posts\/1122\/revisions\/1133"}],"wp:attachment":[{"href":"https:\/\/enisnecipoglu.com\/en\/wp-json\/wp\/v2\/media?parent=1122"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/enisnecipoglu.com\/en\/wp-json\/wp\/v2\/categories?post=1122"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/enisnecipoglu.com\/en\/wp-json\/wp\/v2\/tags?post=1122"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}