How to avoid code redundancy in these two methods, where one has one IEnumerable parameter and one does not?

0

How can I simplify these two methods to prevent code repetition?

Method 1, with the first expression having a generic property of type IEnumerable < >:

public GenericDAO<TModel> LeftJoin<TProperty>(
    Expression<Func<TModel, IEnumerable<TProperty>>> joinMember, 
    Expression<Func<TProperty, TModel, bool>> filter)
    where TProperty : class
{
    var joinMemberMetadata = new Mapping.MapperClass<TProperty>().DoMapper();
    var joinMemberExpression = joinMember.Body as dynamic;
    var filterExpression = filter as dynamic;

    var paramThisModel = filterExpression.Parameters[0].ToString();
    var paramJoinMember = filterExpression.Parameters[1].ToString();

    _query = _query.Trim() + " left join " + joinMemberMetadata.TableName + " as " + 
        joinMemberExpression.Member.Name + " on ";

    _query += filterExpression.Body.ToString()
        .Replace(paramThisModel, _metadataOfClass.TableName)
        .Replace(paramJoinMember, joinMemberExpression.Member.Name)
        .Replace("==", "=")
        .Replace("&&", "and");

    return this;
}

With this method I can use lambda expression in a property of type list, like this:

libroDAO.Query().LeftJoin(livro => livro.Autores, ...)

Method 2, the first expression of this method no longer has the

public GenericDAO<TModel> LeftJoin<TProperty>(Expression<Func<TModel, TProperty>> 
    joinMember, Expression<Func<TProperty, TModel, bool>> filter)
    where TProperty : class
{
    var joinMemberMetadata = new Mapping.MapperClass<TProperty>().DoMapper();
    var joinMemberExpression = joinMember.Body as dynamic;
    var filterExpression = filter as dynamic;

    var paramThisModel = filterExpression.Parameters[0].ToString();
    var paramJoinMember = filterExpression.Parameters[1].ToString();

    _query = _query.Trim() + " left join " + joinMemberMetadata.TableName + " as " + 
        joinMemberExpression.Member.Name + " on ";

    _query += filterExpression.Body.ToString()
        .Replace(paramThisModel, _metadataOfClass.TableName)
        .Replace(paramJoinMember, joinMemberExpression.Member.Name)
        .Replace("==", "=")
        .Replace("&&", "and");

    return this;
}

With this method I can do the same thing for properties of simple classes:

livroDAO.Query().LeftJoin(livro => livro.Editora, ...)
    
asked by anonymous 11.11.2014 / 23:02

2 answers

1

The joinMember parameter and the generic TProperty parameter are only used on the first two rows of both methods. So we can extract all other lines to a common method.

public GenericDAO<TModel> LeftJoin<TProperty>(
    Expression<Func<TModel, IEnumerable<TProperty>>> joinMember, 
    Expression<Func<TProperty, TModel, bool>> filter)
    where TProperty : class
{
    var joinMemberMetadata = new Mapping.MapperClass<TProperty>().DoMapper();
    var joinMemberExpression = joinMember.Body as dynamic;

    LeftJoin(joinMemberMetadata, joinMemberExpression, filter);
}

public GenericDAO<TModel> LeftJoin<TProperty>(Expression<Func<TModel, TProperty>> 
    joinMember, Expression<Func<TProperty, TModel, bool>> filter)
    where TProperty : class
{
    var joinMemberMetadata = new Mapping.MapperClass<TProperty>().DoMapper();
    var joinMemberExpression = joinMember.Body as dynamic;

    LeftJoin(joinMemberMetadata, joinMemberExpression, filter);
}

private GenericDAO<TModel> LeftJoin<TProperty>(
    Mapper<TProperty> joinMemberMetadata, //Nota: eu nao sei qual e' o tipo retornado por .DoMapper
    dynamic joinMemberExpression,
    Expression<Func<TProperty, TModel, bool>> filter)
    where TProperty : class
{
    var filterExpression = filter as dynamic;

    var paramThisModel = filterExpression.Parameters[0].ToString();
    var paramJoinMember = filterExpression.Parameters[1].ToString();

    _query = _query.Trim() + " left join " + joinMemberMetadata.TableName + " as " + 
        joinMemberExpression.Member.Name + " on ";

    _query += filterExpression.Body.ToString()
        .Replace(paramThisModel, _metadataOfClass.TableName)
        .Replace(paramJoinMember, joinMemberExpression.Member.Name)
        .Replace("==", "=")
        .Replace("&&", "and");

    return this;
}
    
12.11.2014 / 09:57
0
public GenericDAO<TModel> LeftJoin<TProperty>(Expression<Func<TModel, TProperty>> 
    joinMember, Expression<Func<TProperty, TModel, bool>> filter)
    where TProperty : class
{
    return LeftJoin(_ => new List<TProperty> { joinMember }, filter);
}

This does not work:

  

Error 1 The best overloaded Add method 'System.Collections.Generic.List.Add (TProperty)' for the collection initializer has some invalid arguments D: \ Projects \ GenericDAO \ GenericDAO \ GenericDAO.cs 125 56 GenericDAO

     

Error 2 Argument 1: can not convert from 'System.Linq.Expressions.Expression >' to 'TProperty' D: \ Projects \ GenericDAO \ GenericDAO \ GenericDAO.cs 125 56 GenericDAO

This works:

return LeftJoin(x => new List<TProperty>(), filter);

Sorry, I'm not registered and so I can not positively respond to good or negative negative responses, much less approve an accepted response.

    
12.11.2014 / 12:45