I am new to c# and now bit confused with Generics and Entity Framework. I have two tables in database, which I retrieve in my code using Entity Framework. On my aspx page, I have a grid which should populate the data based on what table user selects.
In future there will be more tables. So I wanted to write a factory pattern to get the source list for datagrid. I can not make it to work because i am very confused.
Here is my code for BaseClass and two child classes.
static class Factory
{
public static ReportBase GetReport(string name)
{
switch (name)
{
case "Child1":
return new Child1();
case "Child2":
return new Child1();
default:
return null;
}
}
}
//Base Class
class ReportBase<T>
{
public List<T> _list;
public abstract void Load();
public abstract List<T> Filter(DateTime statrtDate, DateTime endDate);
}
//Child 1
class Child1 : ReportBase
{
public List<GetChild1> _list;
public Child1(){}
public override void Load()
{
//GetChild1 is the name of database table
var info = from p in Context.GetChild1 select p;
_list = info.ToList();
}
public List<GetChild1> Filter(DateTime startDate, DateTime endDate)
{
var filteredValues = from p in _list where p.UploadedDate <= startDate select p;
return filteredValues.ToList();
}
}
//Child 2
class Child2 : ReportBase
{
public List<GetChild2> _list;
public Child2() { }
public override void Load()
{
//GetChild2 is the name of database table
return (from p in Context.GetChild2 select p).ToList();
}
public List<GetChild2> Filter(DateTime startDate, DateTime endDate)
{
return (from p in _list where p.UploadedDate <= startDate select p).ToList();
}
}
Can Someone please correct the code accordingly? Do I have to use Generics here? I tried using it in BaseClass but it doesn’t work properly, because I have to fix my child classes accordingly, for which I have no clue.
First of all, with generics you can write better code that is more readable and short.
I think it is better not to use a factory class for repositories in the end you need to know which type you are dealing with it in your code such as:
If you want to use this factory you can do the following:
ReportBase report = Factory.GetReport();
Secondly, it is a bad idea to let your list public because you don’t want to those who are using your class to create a new list from their code such as:
report._list = new List();
You don’t want this thing to happen to the objects in your class. So it is better to have your list private and depend only on the methods to return the data source of your report.
private List _list;
Thirdly, if you implement a generic reportbase you won’t need to write the child classes unless they have something special that the base doesn’t implement.
Fourthly, the current implementation of Filter method is soooo bad because what you are doing here is getting all the records from database then filtering them in memory. This implementation is a bad practice. A better approach is to use the IQueryable which is a deffered execution object i.e. the result won’t be populated until you request it.
So this was a better approach to your problem. I think it is good for you to read a book called “More Effective C# 2008” it talks about queryable and linq in general.
Now if we apply this on your BaseReportClass we can get the following:
Now to defining the additional behavior for the child classes.
This is the code that uses your classes:
Hope this was useful.