简体   繁体   中英

How to access DbSet type dynamically

I'm using LINQ expressions in order to build select and where expressions dynamically.

The select method looks like this:

public Expression<Func<TSource, TTarget>> GetSelectExpression<TSource, TTarget>()
    {
        ParameterExpression l_pe = Expression.Parameter(Base_type, "source");  
...            
        Expression<Func<TSource, TTarget>> l_return = Expression.Lambda<Func<TSource, TTarget>>(l_select, new ParameterExpression[] { l_pe });
        l_return.Compile();

        return l_return;
    }

The Where method looks like the following:

public Expression<Func<TTarget, bool>> GetWhereExpression<TTarget>()
    {
        ParameterExpression l_pe = Expression.Parameter(Dto_type, "dto");

        ....

        Expression<Func<TTarget, bool>> l_return = Expression.Lambda<Func<TTarget, bool>>(l_or, new ParameterExpression[] { l_pe });
        l_return.Compile();

        return l_return;
    }

If I call the following statements, everything works fine:

var l_where = GetWhereExpression<CrudChangetaskDto>();
var l_select = GetSelectExpression<A_Changetask, CrudChangetaskDto>();               

IQueryable<CrudChangetaskDto> l_query = l_db.A_Changetask.Select(l_select).Where(l_where);
var lt_result = l_query.ToList();

Because of using the WHERE and SELECT methods more dynamically, I like to have a method returning an IQueryable like the following (PaltrConnect is the database context):

IQueryable<TTarget> GetSearchhelpvalue<TSource, TTarget>(PaltrConnect context)
    {   
        var l_dbset = context.Set(typeof(TSource));            

        IQueryable<TTarget> l_query = l_dbset.Select(GetSelectExpression<TSource,TTarget>()).Where(GetWhereExpression<TTarget>());
        return l_query;
    }

Unfortunately, this is syntactically not correct. I get the error message System.Linq.IQueryable cannot be converted into System.Linq.IQueryable.

Finally, I like to call GetSearchhelpvalue in the following way:

using (var l_db = new PaltrConnect)
  {
    IQueryable<CrudChangeTaskDto> l_query = GetSearchhelpvalue<A_Changetask, CrudChangetaskDto>(l_db);
    var lt_result = l_query.ToList();
  }

How can I access the DbSet of the type which corresponds to TSource or how can this be solved?

Yours Stephan

You are so close. Just instead of the non generic DbContext.Set(Type) use the generic DbContext.Set<TEntity>() overload like this

IQueryable<TTarget> GetSearchhelpvalue<TSource, TTarget>(PaltrConnect context)
    where TSource : class
{   
    return context.Set<TSource>()            
        .Select(GetSelectExpression<TSource,TTarget>())
        .Where(GetWhereExpression<TTarget>());
}

Note that it requires class constraint.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM