3

Suppose I have a base class and inherited class

public class BaseClass
{
    public String SystemName { get; set; }
    public String UserName { get; set; }
}

internal class InheritedClass : BaseClass
{
    public Guid Id { get; set; }        
}

Some expression over base class is passed to my module from outside (inherited class is not visible from there)

Expression<Func<BaseClass, bool>>

It describes some filtering logic, for example like that

Expression<Func<BaseClass, bool>> filter = x => x.SystemName.StartsWith("ABC") && x.UserName != ""

But inside my module I need to use

Expression<Func<InheritedClass, bool>>

Because I apply this filter to IQueryable, like that

IQueryable<InheritedClass> filteredItems = Items.Where(filter);

Inherited class has all properties of base class - so my not-so-experienced mind suppose convertation is possible :)

Is there any way to convert passed expression to what I need?

Thank you.

bairog
  • 3,143
  • 6
  • 36
  • 54

1 Answers1

0

Use this Utility class

public static class Utility
{
    //public static IEnumerable<TTarget> Where<TSource, TTarget>(this IEnumerable<TSource> source, Expression<Func<TSource, bool>> predicate) where TTarget : class, TSource
    //{
    //     return source.Where(obj => obj is TTarget).Where(predicate.Compile()).Select(obj => obj as TTarget);
    //}

    public static IQueryable<TTarget> Where<TSource, TTarget>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate) where TTarget : class, TSource
    {
        return source.Where(obj => obj is TTarget).Where(predicate).Select(obj => obj as TTarget);
    }
}

Example is like this, The super and sub classes like

class Person
{
    public String Name { get; set; }
    public ushort Age { get; set; }
}

class Student : Person
{
    public String StudentId { get; set; }
}

class Teacher : Person
{
    public String TeacherId { get; set; }
}

use the utility and test it

            /*List of Persons*/
            List<Person> persons = new List<Person>()
                                                          {
                                                              new Student(){StudentId = "Std-01", Name = "Roy", Age = 24},
                                                              new Student(){StudentId = "Std-02", Name = "Jhon", Age = 25},
                                                              new Teacher(){TeacherId = "Tch-01", Name = "Roy", Age = 24},
                                                              new Teacher(){TeacherId = "Tch-02", Name = "Jhon", Age = 25}
                                                          };
            /*predictions*/
            Expression<Func<Person, bool>> prediction = x => x.Name.Contains("o");


            /*Use the utility*/
                                                                    /*Get Teacher from Persons*/
            IQueryable<Teacher> filteredItems = persons.AsQueryable().Where<Person, Teacher>(prediction);
            List<Teacher> result = filteredItems.ToList();

In result we will get the teacher with TeacherId="Tch-01" And "Tch-02"

All though I worked with IEnumerable not with IQueryable, but wish it would be helpfull

Dipon Roy
  • 396
  • 1
  • 4
  • 18
  • it's most likely applied to an IQueryable for a reason, that reason is usually that the expression is translated to SQL or similar so calling compile would probably go against the intention – Rune FS Nov 04 '13 at 12:38
  • @Rune FS : i thought the intension was to get List form the List using the provided the Expression, bool> so made such example. but it seems that the main process asked to convert the Expression, bool> to Expression> so sorry from the misunderstanding. – Dipon Roy Nov 04 '13 at 12:55
  • Yeah and my point is that it's explicitly stated in the question that it's an Iqueryable "Because I apply this filter to IQueryable, like that" – Rune FS Nov 04 '13 at 12:57
  • now my question is that, you will provided Expression, bool>, and IQueryable, and want to get the IQueryable. am i missing some thing – Dipon Roy Nov 04 '13 at 13:01
  • Eh that's not a question but it would seem that this is a pointless discussion. The question has been closed because it was already answered and we're debating an answer that does match the question that was already answered – Rune FS Nov 04 '13 at 13:05
  • @Rune FS: plz don't take this as debating, I am only trying to provide a solution ... I do have changed the IEnumerable to IQueryable. Your advice would always valued – Dipon Roy Nov 04 '13 at 13:45
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/40502/discussion-between-dipon-roy-and-rune-fs) – Dipon Roy Nov 04 '13 at 13:51