开发者

Generic custom linq filter

How开发者_开发问答 can I create a custom generic linq filter that will check if the generic class contains a property name and returns the query...

I have something like:

    public static IQueryable<T> GetAllByType<T>(
        this IQueryable<T> customQuery, string seller) where T : class, new()
    {
        customQuery = customQuery.Where(i => i.GetType().Name == "TypeOfSeller");
        return customQuery;
    }

If the property type on the table T exists then I want to filter the expression using the string seller passed in as a parameter...

simply: return an expression which will filter this table by the seller param which could be "big", "small" etc.


I think this does what you describe.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace ConsoleApplication3
    {
        class Seller
        {
            public string Name { get; set; }
            public string TypeOfSeller { get; set; }
        }

        class SomeOtherData
        {
            public string Name { get; set; }
        }

        static class Program
        {


            static void Main(string[] args)
            {
                List<Seller> sellers = new List<Seller>();
                sellers.Add(new Seller() { Name = "A", TypeOfSeller = "Test" });
                sellers.Add(new Seller() { Name = "B", TypeOfSeller = "Test" });
                sellers.Add(new Seller() { Name = "C", TypeOfSeller = "Other" });

                var q = from p in sellers.AsQueryable<Seller>().GetAllByType("Test") select p;

                List<SomeOtherData> other = new List<SomeOtherData>();
                other.Add(new SomeOtherData() { Name = "A" });
                other.Add(new SomeOtherData() { Name = "B" });
                other.Add(new SomeOtherData() { Name = "C" });

                var q2 = from p in other.AsQueryable<SomeOtherData>().GetAllByType("Test") select p;

                foreach (var x in q)
                    Console.WriteLine(x.Name + ", " + x.TypeOfSeller);

                Console.WriteLine("Other Data: ");

                foreach (var x in q2)
                    Console.WriteLine(x.Name);


                Console.ReadLine();
            }

            public static IQueryable<T> GetAllByType<T>(this IQueryable<T> customQuery, string seller) where T : class, new()
            {
                var prop = typeof(T).GetProperty("TypeOfSeller");
                if(prop != null)
                  customQuery = customQuery.Where(i => prop.GetValue(i, new object[] {}).ToString() == seller);
                return customQuery;
            }
        }
    }

The output is:

  • A, Test
  • B, Test
  • Other Data:
  • A
  • B
  • C


I would refactor it a bit so that there's no "if" involved but that I'm only sending the entities that qualify to the method.

The next thing you want to consider is that if there are multiple entity models that share a property name and you want to share logic regarding that property name, utilize the partial aspect of the code-generated classes to extend those classes and have each of them implement an interface.

interface ISeller 
{
    string TypeOfSeller { get; set; }
}

This will allow you to add the interface to the list of constraints on the method and also allow you to simply utilize the TypeOfSeller property directly without trying to resort to other methods (such as reflection).


The question is not very clear but sounds like you want something like this

public static IQueryable<T> GetAllByType<T>(
    this IQueryable<T> customQuery, string seller) where T : class, new()
{
    return from i in customQuery
                let prop = typeof(T).GetProperty("SellerType")
                where prop != null && prop.GetValue(i, null).Equals(seller) 
                select i;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜