public class Address
{
public string City { get; set; }
public string Street { get; set; }
}
public class User
{
public Address Address1 { get; set; }
public Address Address2 { get; set; }
}
public class DefaultAddressSortingSpecification<TEntity>
{
private readonly Expression<Func<TEntity, Address>> _keySelector;
public DefaultAddressSortingSpecification(Expression<Func<TEntity, Address>> keySelector)
{
_keySelector = keySelector;
}
public IQueryable<TEntity> OrderingEntitiesFrom(IQueryable<TEntity> query)
{
//order by city
//order by street
}
}
usage:
var s1 = new DefaultAddressSortingSpecification<User>(user => user.Address1);
var s2 = new DefaultAddressSortingSpecification<User>(user => user.Address2);
I would like to have universal AddressSortingSpecification. _keySelector points to Address entity. How to add City or Street to it?
Normally I can write something like this: user.Address1.City
As I understand the question, you want to know how to create expressions to access the City
and Street
properties of an Address
when given an expression which only references an Address
. Here's how I would do it:
public IQueryable<TEntity> OrderingEntitiesFrom(IQueryable<TEntity> query)
{
var parameter = _keySelector.Parameters.Single();
var address = _keySelector.Body;
var citySelector = Expression.Lambda<Func<TEntity, string>>(Expression.Property(address, "City"), parameter);
var streetSelector = Expression.Lambda<Func<TEntity, string>>(Expression.Property(address, "Street"), parameter);
return query.OrderBy(citySelector).ThenBy(streetSelector);
}