How to avoid code redundancy in these two methods, one having a Ienumerable<> parameter and the other not?

Asked

Viewed 98 times

0

How can I simplify these two methods in order 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 list type property, like this:

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

Method 2, the first expression of this method no longer has Ienumerable<>:

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 simple class properties:

livroDAO.Query().LeftJoin(livro => livro.Editora, ...)

2 answers

1

The parameter joinMember and the generic parameters TProperty are only used in the first two lines of both methods. Then we can extract all other lines for 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;
}

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);
}

That doesn’t 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: cannot Convert from 'System.Linq.Expressions.Expression>' to 'Tproperty' D: Genericdao Genericdao Genericdao.Cs 125 56 Genericdao

Already it works:

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

Teste do método

I’m sorry, I’m not registered and so I can’t give good answers or negative bad answers, let alone approve an accepted answer.

  • And why not register? It’s so easy, nor need to fill out any registration.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.