snippetcsharpMinor
Improving a Cheese Filter loading in C#
Viewed 0 times
filterloadingimprovingcheese
Problem
Let's say that i have a database which contain cheese. I love cheese.
Depending on the request my server is getting (c# WebApi), i have to filter user data accordingly.
Maybe the user wants to only get cheese up to a certain date, or from a certain date, or between to dates. Maybe he wants all french cheese, or american cheese.
My model works, but i dont like switchs, and i feel like there is a better way.
The model is as follow :
This model is what's get filled
Now, i'm creating a tuple which will hold the StoredProcedure name (Basically, a select with where, order by, etc), its parameters, and the choosen filter, like so :
And where i actually fill it :
```
public bool CheeseFilterTuple()
{
bool flag = false;
List options = new List();
String SPName = "ERROR";
DateTime tmp = new DateTime(); // ForChecking GoodFormating of datetimes
DateTime tmp2 = new DateTime();
switch (GetMode().Value)
{
case CheeseFilter.DateFrom:
flag = !String.IsNullOrWhiteSpace(dateStart) && DateTime.TryParseExact(dateStart, TMP_DATEFORMAT, CultureInfo.InvariantCulture, DateTimeStyles.None, out tmp);;
options.Add( new SqlParameter() { Name = "@DateStart", Value = tmp.ToString("yyyyMMdd")});
SPName = "Cheese_FromDate";
break;
case CheeseFilter.DateStart:
flag = !String.IsNullOrWhiteSpace(dateEnd) && DateTime.TryParseExact(dateEnd,
Depending on the request my server is getting (c# WebApi), i have to filter user data accordingly.
Maybe the user wants to only get cheese up to a certain date, or from a certain date, or between to dates. Maybe he wants all french cheese, or american cheese.
My model works, but i dont like switchs, and i feel like there is a better way.
The model is as follow :
namespace myAPI.Models
{
public enum CheeseFilter
{
Country,
DateFrom,
DateStart,
DateBetween,
};
public class FilterQuery
{
public CheeseFilter? filter { get; set; }
public DateTime? DateStart{ get; set; }
public DateTime? DateEnd{ get; set; }
public String Country{ get; set; }
}
}This model is what's get filled
[FromPost]Now, i'm creating a tuple which will hold the StoredProcedure name (Basically, a select with where, order by, etc), its parameters, and the choosen filter, like so :
private Tuple> LoadedCheeseWithOptions;And where i actually fill it :
```
public bool CheeseFilterTuple()
{
bool flag = false;
List options = new List();
String SPName = "ERROR";
DateTime tmp = new DateTime(); // ForChecking GoodFormating of datetimes
DateTime tmp2 = new DateTime();
switch (GetMode().Value)
{
case CheeseFilter.DateFrom:
flag = !String.IsNullOrWhiteSpace(dateStart) && DateTime.TryParseExact(dateStart, TMP_DATEFORMAT, CultureInfo.InvariantCulture, DateTimeStyles.None, out tmp);;
options.Add( new SqlParameter() { Name = "@DateStart", Value = tmp.ToString("yyyyMMdd")});
SPName = "Cheese_FromDate";
break;
case CheeseFilter.DateStart:
flag = !String.IsNullOrWhiteSpace(dateEnd) && DateTime.TryParseExact(dateEnd,
Solution
Your code is really hard to follow. It reads and modifies a lot of local fields/properties that are somewhere hidden. I tried to refactor it but it's still buggy I believe as some parameters are unclear. Nevertheless it should give you an idea how to improve it.
Using
You should pass all the parameters that the function needs instead reading them from the some fields or properties... unless it's a part of some class which we don't know.
In particular you could create filter criteria for passing the parameters and return a cheese filter as a result.
You don't need to check the date string for null/empty, the
Work on your variable names. tmp, tmp2 are not good at all. Give them real names, like dateStart or dateEnd or even tmpDateStart but just tmp isn't good enough.
Here's an example that I managed to piece together:
Using
Tuple is a quick and dirty way to test something because you almost instantly forget what the properties are for as they are simply named ItemX. If you plan to use this code longer then just for experiments I'd use a real class.You should pass all the parameters that the function needs instead reading them from the some fields or properties... unless it's a part of some class which we don't know.
In particular you could create filter criteria for passing the parameters and return a cheese filter as a result.
You don't need to check the date string for null/empty, the
TryParse won't throw on null, that's what it is for.Work on your variable names. tmp, tmp2 are not good at all. Give them real names, like dateStart or dateEnd or even tmpDateStart but just tmp isn't good enough.
Here's an example that I managed to piece together:
public class FilterCriteria
{
public CheeseFilter? filter { get; set; }
public string DateStart { get; set; }
public string DateEnd { get; set; }
public String Country { get; set; }
}
class CheeseFilter
{
public FilterCriteria Criteria { get; set; }
public string SPName { get; set; }
public List SqlParameters { get; set; }
}
public CheeseFilter CreateCheeseFilter(FilterCriteria filterCriteria)
{
var isValidDateFormat = false;
var sqlParameters = new List();
var SPName = "ERROR";
var dateStart = new DateTime(); // ForChecking GoodFormating of datetimes
var dateEnd = new DateTime();
switch (GetMode().Value)
{
case CheeseFilter.DateFrom:
isValidDateFormat = DateTime.TryParseExact(filterCriteria.DateStart, TMP_DATEFORMAT, CultureInfo.InvariantCulture, DateTimeStyles.None, out tmp);;
if (!isValidDateFormat) retrun null;
sqlParameters.Add(new SqlParameter() { Name = "@DateStart", Value = tmp.ToString("yyyyMMdd")});
SPName = "Cheese_FromDate";
break;
case CheeseFilter.DateStart:
isValidDateFormat = DateTime.TryParseExact(filterCriteria.DateStart, TMP_DATEFORMAT, CultureInfo.InvariantCulture, DateTimeStyles.None, out tmp);
if (!isValidDateFormat) retrun null;
sqlParameters.Add(new SqlParameter() { Name = "@DateEnd", Value = tmp.ToString("yyyyMMdd") });
SPName = "Cheese_To_Date";
break;
case CheeseFilter.BetweenDates:
isValidDateFormat =
DateTime.TryParse(filterCriteria.DateStart, out dateStart) &&
DateTime.TryParse(filterCriteria.DateEnd, out dateEnd);
if (!isValidDateFormat) retrun null;
sqlParameters.Add( new SqlParameter() { Name = "@DateStart",Value = tmp.ToString("yyyyMMdd")}); //Converting for sqlServer
sqlParameters.Add( new SqlParameter() { Name = "@DateEnd", Value = tmp2.ToString("yyyyMMdd")});
SPName = "Cheese_Between_Date";
break;
}
return new CheeseFilter
{
Criteria = GetMode().Value
SPName = SPName
SqlParameters = options
};
}Code Snippets
public class FilterCriteria
{
public CheeseFilter? filter { get; set; }
public string DateStart { get; set; }
public string DateEnd { get; set; }
public String Country { get; set; }
}
class CheeseFilter
{
public FilterCriteria Criteria { get; set; }
public string SPName { get; set; }
public List<SqlParameter> SqlParameters { get; set; }
}
public CheeseFilter CreateCheeseFilter(FilterCriteria filterCriteria)
{
var isValidDateFormat = false;
var sqlParameters = new List<SqlParameter>();
var SPName = "ERROR";
var dateStart = new DateTime(); // ForChecking GoodFormating of datetimes
var dateEnd = new DateTime();
switch (GetMode().Value)
{
case CheeseFilter.DateFrom:
isValidDateFormat = DateTime.TryParseExact(filterCriteria.DateStart, TMP_DATEFORMAT, CultureInfo.InvariantCulture, DateTimeStyles.None, out tmp);;
if (!isValidDateFormat) retrun null;
sqlParameters.Add(new SqlParameter() { Name = "@DateStart", Value = tmp.ToString("yyyyMMdd")});
SPName = "Cheese_FromDate";
break;
case CheeseFilter.DateStart:
isValidDateFormat = DateTime.TryParseExact(filterCriteria.DateStart, TMP_DATEFORMAT, CultureInfo.InvariantCulture, DateTimeStyles.None, out tmp);
if (!isValidDateFormat) retrun null;
sqlParameters.Add(new SqlParameter() { Name = "@DateEnd", Value = tmp.ToString("yyyyMMdd") });
SPName = "Cheese_To_Date";
break;
case CheeseFilter.BetweenDates:
isValidDateFormat =
DateTime.TryParse(filterCriteria.DateStart, out dateStart) &&
DateTime.TryParse(filterCriteria.DateEnd, out dateEnd);
if (!isValidDateFormat) retrun null;
sqlParameters.Add( new SqlParameter() { Name = "@DateStart",Value = tmp.ToString("yyyyMMdd")}); //Converting for sqlServer
sqlParameters.Add( new SqlParameter() { Name = "@DateEnd", Value = tmp2.ToString("yyyyMMdd")});
SPName = "Cheese_Between_Date";
break;
}
return new CheeseFilter
{
Criteria = GetMode().Value
SPName = SPName
SqlParameters = options
};
}Context
StackExchange Code Review Q#132954, answer score: 2
Revisions (0)
No revisions yet.