I have a generic repository with the following method
IQueryable<T> GetAllByFilter(Expression<Func<T, bool>> expression);
I'm now trying to provide a search feature through the front end, where one or more parameters might have been entered or 开发者_如何转开发left blank. I'm having problems short-circuiting the expression for empty parameters.
The problem can be demonstrated by calling the following example on the repository:
public IEnumerable<Foo> Search(string param)
{
var filteredFoos = _fooRepository.GetAllByFilter(
f => string.IsNullOrEmpty(param) || f.Something == param );
return filteredFoos.ToList(); // throws exception
}
Enumerating the query with ToList()
throws a System.NullReferenceException
if param
is null
.
I neither understand this nor know how to fix it, so any pointers appreciated. Thanks.
UPDATE: in response to the comments below, I added a null check. My actual code looks like this now
var test1 = _repository.GetAllByFilter(
r => r != null &&
(string.IsNullOrEmpty(param)
|| (r.Field != null && r.Field.IndexOf(param.Trim()) != -1)));
var test2 = test1.ToList(); // exception here
I'm still not seeing where the problem could be.
EDIT: in response to comment, the generic repository GetAllByFilter
code:
public IQueryable<T> GetAllByFilter(Expression<Func<T, bool>> expression)
{
return _dataContext.GetTable<T>().Where(expression);
}
note that if I run a simple GetAll
query
public IQueryable<T> GetAll()
{
return _dataContext.GetTable<T>();
}
on the same table, no null
records are returned (as expected).
keep it simple:
public IEnumerable<Foo> Search(string param)
{
if (string.IsNullOrEmpty(param))
{
return this.fooRepository.GetAll().ToArray();
}
return this.fooRepository.GetAllByFilter(o => o.Field.Contains(param.Trim())).ToArray();
}
cake.
public IEnumerable<Foo> Search(string param)
{
Expression<Func<Foo, bool>> shortCircuit = a => true;
Expression<Func<Foo, bool>> normal = a => a.Something == param;
var filteredFoos = _fooRepository.GetAllByFilter(
string.IsNullOrEmpty(param) ? shortCircuit : normal);
return filteredFoos.ToList(); // no more exception.
}
You just gotta remember, you can't throw anything into those IQueryable methods and expect them to understand. You can probably make shortCircuit expression to static.
精彩评论