The question is very similar to Dynamically generate LINQ select with nested properties
public static Expression<Func<TSource, TTarget>> BuildSelector<TSource, TTarget>(string members) =>
    BuildSelector<TSource, TTarget>(members.Split(',').Select(m => m.Trim()));
public static Expression<Func<TSource, TTarget>> BuildSelector<TSource, TTarget>(IEnumerable<string> members)
{
    var parameter = Expression.Parameter(typeof(TSource), "e");
    var body = NewObject(typeof(TTarget), parameter, members.Select(m => m.Split('.')));
    return Expression.Lambda<Func<TSource, TTarget>>(body, parameter);
}
static Expression NewObject(Type targetType, Expression source, IEnumerable<string[]> memberPaths, int depth = 0)
{
    var bindings = new List<MemberBinding>();
    var target = Expression.Constant(null, targetType);
    foreach (var memberGroup in memberPaths.GroupBy(path => path[depth]))
    {
        var memberName = memberGroup.Key;
        var targetMember = Expression.PropertyOrField(target, memberName);
        var sourceMember = Expression.PropertyOrField(source, memberName);
        var childMembers = memberGroup.Where(path => depth + 1 < path.Length);
        var targetValue = !childMembers.Any() ? sourceMember :
            NewObject(targetMember.Type, sourceMember, childMembers, depth + 1);
        bindings.Add(Expression.Bind(targetMember.Member, targetValue));
    }
    return Expression.MemberInit(Expression.New(targetType), bindings);
}
The nice generic solution provided by Ivan Stoev works fine but the problem is that it doesn't support collection properties.
For example, source.Property1.Property2 - if Property1 is collection of users than the code doesn't work as Property2 is not the property of the collection but of the Property1 type.
class Shipment {
   // other fields...
   public int Id;
   public Address Sender;
   public List<Address> Recipients;
}
class Address {
    public string AddressText;
    public string CityName;
    public string CityId;
}
With the classes and code above I can query
var test = BuildSelector<Shipment, Shipment>(
    "Id, Sender.CityId, Sender.CityName");
But if I want to get only city names for recipients I cannot do the following (because recipients is collection) :
var test = BuildSelector<Shipment, Shipment>(
    "Recipients.CityName");
I am new to C# expressions and cannot figure out how to improve the above mentioned solution to make it work with collection properties.