Patterns for using linq-to-nh in service layer

0 views
Skip to first unread message

Nieve

unread,
Nov 14, 2009, 10:03:35 AM11/14/09
to altnetisrael
שלום לכולם

I've been looking into handling calls to my DAL for executing
searches.
The app I'm working on uses ASP.NET MVC + linq-to-nh, so that when we
get on our controller the fields that the user wishes to search we
simply forward them to the Service which will call the DAL. Thing is,
we don't know which fields did the user fill and which did he leave
empty, so that we always need to verify which are not null or empty.
Seeing that there is a pattern here, I though of writing a solution
that'll target this in a more generic way, but am not sure to what
extent this would be profitable. The idea I came up with was that:
In my DAL I have this method:
public IList<User> GetBy(Expression<Func<User, bool>> criteria)
{
if (criteria == null) return new List<User>();
return Session.Linq<User>().Where(criteria).ToList();
}

My service will then do something like that:
Expression<Func<User,bool>> criteria = null;
criteria = criteria.GetCriteria(user, u => u.Name, u => u.Birthdate);
List<User> list = myDal.GetBy(criteria);

Now, the the heart of the logic is found in the extension method I
wrote for Expression<Func<User,bool>> (this is just a partial
example):

public static class ExpressionCriteriaExtensions
{
public static Expression<Func<T, bool>> GetCriteria<T>(this
Expression<Func<T, bool>> ret, T instance, params Expression<Func<T,
object>>[] criteriaProperties)
{
foreach (var expression in criteriaProperties)
{
Func<T, object> func = expression.Compile();
object propertyValue = func(instance);
ret = ret.GetStringEqCriteria(func, propertyValue);
ret = ret.GetDateEqCriteria(func, propertyValue);
}

return ret;
}

private static Expression<Func<T, bool>>
GetStringEqCriteria<T>
(this Expression<Func<T, bool>> ret, Func<T, object> func, object
propertyValue)
{
string stringValue = propertyValue as string;
if (!string.IsNullOrEmpty(stringValue))
{
Func<T, object> tmp = func;
if (tmp != null)
{
if (ret == null) ret = t => tmp(t) == stringValue;
else
{
Func<T, bool> currentCriteria = ret.Compile();
ret = t => currentCriteria(t) && tmp(t) ==
stringValue;
}
}
}
return ret;
}

private static Expression<Func<T, bool>> GetDateEqCriteria<T>
(this Expression<Func<T, bool>> ret, Func<T, object> func, object
propertyValue)
{
if (propertyValue is DateTime)
{
DateTime dateTimeValue = (DateTime)propertyValue;
Func<T, object> tmp = func;
if (tmp != null)
{
if (ret == null) ret = t => (DateTime)tmp(t) ==
dateTimeValue;
else
{
Func<T, bool> currentCriteria = ret.Compile();
ret = t => currentCriteria(t) && (DateTime)tmp
(t) == dateTimeValue;
}
}
}
return ret;
}
}


Is it completely redundant? Does this make any sense? Or should I use
instead a method per use case in my DAL(repository) that'll return an
IQUeryable<User> (ie GetByName, GetByBirthdate etc')? Any other ideas?
Would appreciate any feedback :)
Reply all
Reply to author
Forward
0 new messages