jeudi 23 février 2017

dynamically filtering a List using Reflection in LINQ

Hi I am working on a UWP application using the MVVM pattern.

What parameters do I have:

I have an IDictionary<string,bool> with the key with the name of the property (string) and the value as a bool that should be the value of the property.

What I am trying to achieve:

I want to create a generic List<T> filter method that would take in the parameter I have defined above and return all items from that List in which the Key property has the Value value from the IDictionary<string,bool>. My best guess was to use Reflection but got lost in the process. I need help.

The Code:

My Class of which the List is:

public class fooClass
{
    public string FooName { get; set; }

    public int FooId { get; set; }

    public bool AdminAccess { get; set; }

    public bool ChildRestrictions { get; set; }

    public List<ChannelInfo> RestrictedChannels { get; set; }
}

My property for setting the collection of filters

 private IDictionary<string, bool> filterBasedOnBoolCollection;
    public IDictionary<string, bool> FilterBasedOnBoolCollection
    {
        get { return filterBasedOnBoolCollection; }
        set
        {
            filterBasedOnBoolCollection = value;
            FilterByBoolValue(value);
            RasiePropertyChanged(nameof(FilterBasedOnBoolCollection));
            RasiePropertyChanged(nameof(GetAllUsersWithFilterIfAny));
        }
    }

My Getter Property for the filtering process:

public ObservableCollection<fooClass> GetAllUsersWithFilterIfAny
    {
        get
        {
            IEnumerable<fooClass> intitialAllUsersFilter = AllUsersCollection;


            //For Name containing "string" filter.
            if (!string.IsNullOrEmpty(FilterQueryString?.Trim()))
                intitialAllUsersFilter = intitialAllUsersFilter.Where(x => x.FooName.ToLower().Contains(FilterQueryString.ToLower()));

            //For BoolProperty value matching filter.
            if (FilterBasedOnBoolCollection?.Count > 0)
            {
                for (int i = 0; i < FilterBasedOnBoolCollection.Count; i++)
                {
                    var propName = FilterBasedOnBoolCollection.Keys.ElementAt(i);

                    var value = GetType().GetProperty(propName);

                    bool propMatchingValue = FilterBasedOnBoolCollection.Values.ElementAt(i);

                    //var first = intitialAppTypeDeviceFilter.Select(x => x.GetType().GetProperties().ToList().Select(p => p.GetType().GetProperty(propName)).ToList());
                    fooClass tda = new fooClass();
                    var first = tda.GetType().GetProperties().ToList();
                    var S = first.Select(x => x.GetType().GetProperty(propName));
                    var p = first.Select(x => x.GetType().GetProperty(propName).GetValue(x, null));

                    intitialAllUsersFilter = intitialAllUsersFilter.Where(x => (bool)x.GetType().GetProperty(propName).GetValue(x, null) == propMatchingValue);
                }
            }

            return intitialAllUsersFilter.ToObservableCollection();

        }
    }

The above is all I've tried. I tried to separate the linq query too just to see the outputs. Clearly I don't have it figured out yet because as soon I try the codes I get an error at the intermediate window:

{System.Linq.Enumerable.WhereEnumerableIterator<Intouch.BlackBox.Outlets.AllDeviceDataOutlet>} Error: Evaluation of method System.Linq.SystemCore_EnumerableDebugView 1[Intouch.BlackBox.Outlets.AllDeviceD ataOutlet].get_Items() calls into native method System.Func 2[Intouch.BlackBox.Outlets.AllDeviceDataOutlet,System.Boolean].Invok e(). Evaluation of native methods in this context is not supported.


Please Note The filter process is below:

  1. Type the matching name (Containing clause of the string).
  2. from the resultant Data (of those who's name has the matching keywords from the query), fetch the items in which AdminAccess == true && ChildRestrictions == false




Aucun commentaire:

Enregistrer un commentaire