How get Expression.Lambda> generic

c# entity-framework-core linq

Question

I had the following code and I want to replace the Department type for a generic type...

I would do like to replace...

Expression.Lambda<Func<Department, bool>>(body, param)

by..

 Expression.Lambda<Func<T, bool>>(body, param)

I know that I must use reflection, but all I have is a domain model class boxed as object.

I could get the object and his type name but I am having hard to replace the hard coded type Department by a generic type.

I can't convert method Exists to Exists<T> because I don't know what <T> is at the time of calling the method. I only have the object.

public bool Exists(object id, object source, Type type)
{
    var param = Expression.Parameter(type, "e");
    var body = Expression.Equal(Expression.Property(param, "Id", Expression.Constant(id));
    var where = Expression.Lambda<Func<Department, bool>>(body, param);

    var context = new DataContext();

    var dbSet = context.Set<Department>();

    return dbSet.AsNoTracking().Any(where);
}

For the dbset case I tried the following code

public static IQueryable<object> Set (this DbContext context, Type type)
{
 return IQueryable<object>)context.GetType().GetMethod("Set")?.MakeGenericMethod(type).Invoke(context, null);
}

and replace...

var dbSet = context.Set<Department>();

by

var dbSet = context.Set(type);

It seems to work, I got the right dbset but there are some issues with the where clause that gives some run time errors.

What I am trying to achieve is avoid EF Core to do client side evaluation. I.e.

Any(e => e.ToString == id.ToString())

this will work but will perform an undesirable client side evaluation.

1
3
10/8/2018 11:30:21 PM

Popular Answer

I can't convert method Exists to Exists<T> because I don't know what <T> is at the time of calling the method. I only have the object.

That is where generics would help with the generation of the dynamic lambda expression.

public class MyEntity
{
    public int Id { get; set; }
}

public class muckingabout
{
    public bool Exists<T>(T myentity) where T: MyEntity
    {
        var type = typeof(T);
        //e =>
        var param = Expression.Parameter(type, "e");
        //e => e.Id    
        var property = Expression.Property(param, "Id");
        var value = Expression.Constant(myentity.Id);
        //e => e.Id == myentity.Id
        var body = Expression.Equal(property, value);
        var lambda = Expression.Lambda<Func<T, bool>>(body, param);

        using (var context = new DbContext())
        {
           var dbSet = context.Set<T>();
           return dbSet.AsNoTracking().Any(lambda);
        }
    }
}
3
10/9/2018 12:34:46 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow