Entity Framework Repository Pattern Custom Filter using Dynamic Linq

Berikut adalah contoh penanganan filter custom menggunakan repository pattern dan Dynamic Linq. Misalnya untuk kasus many-to-many, atau filter berdasarkan atribut lain dari tabel foreign key.

RemoveFilterField dan Clone adalah fungsi tambahan pada kelas FilterInfo

[code language=”csharp”]
public List<post> Find(int? skip = null, int? take = null, List<SortingInfo> sortings = null, FilterInfo filters = null, bool isPublishOnly = true)
{
IQueryable<post>> list = context.post;
string categoryIdParam = null, categoryTitleParam = null;
FilterInfo copyFilters = null;

//filter
if (filters != null)
copyFilters = filters.Clone();

if (copyFilters != null && (copyFilters.Filters != null && copyFilters.Filters.Count > 0))
{
copyFilters.FormatFieldToUnderscore();

categoryIdParam = copyFilters.RemoveFilterField("category_id"); //menangani filter by category id
categoryTitleParam = copyFilters.RemoveFilterField("category_title");

GridHelper.ProcessFilters<post>(copyFilters, ref list);
}

//menangani category_id
if (categoryIdParam != null)
{
int categoryId = int.Parse(categoryIdParam);
list = list.Where(m => m.post_category.Any(c => c.id == categoryId));
}

//menangani category_title
if (categoryTitleParam != null)
{
list = list.Where(m => m.post_category.Any(c => c.title == categoryTitleParam));
}

if (sortings != null && sortings.Count > 0)
{
foreach (var s in sortings)
{
s.FormatSortOnToUnderscore();
list = list.OrderBy<post>(s.SortOn + " " + s.SortOrder);
}
}
else
{
list = list.OrderBy<post>("id desc"); //default, wajib ada atau EF error
}

//filter
list = list.Where(i => i.deleted == false);
if (isPublishOnly)
list = list.Where(i => i.status == "PUBLISH");

//take amp; skip
var takeList = list;
if (skip != null)
{
takeList = takeList.Skip(skip.Value);
}
if (take != null)
{
takeList = takeList.Take(take.Value);
}

//return result
List<post> result = takeList.ToList();

return result;
}
[/code]

[code language=”csharp”]
/**
* menghapus filter dengan field tertentu
* batasan: belum rekursif
* @return null kalau tidak ditemukan, atau nilai dari field tsb
*/
public string RemoveFilterField(string field)
{
int initCount = Filters.Count;
string val = Filters.Where(m => m.Field == field.ToLower()).Select(m => m.Value).FirstOrDefault();

if (val != null)
{
Filters.RemoveAll(m => m.Field == field.ToLower());
}

return val;
}

public FilterInfo Clone()
{
FilterInfo clone = new FilterInfo { Field = this.Field, Logic = this.Logic, Operator = this.Operator, Value = this.Value };

if (Filters != null)
{
clone.Filters = new List<FilterInfo>();
foreach (var f in Filters)
{
clone.Filters.Add(f.Clone());
}
}

return clone;
}

[/code]

Chandra Oemaryadi has written 244 articles

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>