I have a list with multiple columns. I want to filter the list based on the requested column name (column name will come as a parameter) with distinct values.
IList<obj1> objTemp= new List<obj1>();
for (int i = 0; i < 15; i++)
{
obj1 temp= new obj1();
temp.Name = "Name" + i;
temp.Age= "Age" + i;
temp.Company= "Company" + i;
objTemp.Add(temp);
}
var distinctTypeIDs = objTemp.Select(x => x.**{my requested column}**).Distinct();
You can use reflection for getting desired property by it's name:
var distinctTypeIDs = objTemp.Select(x => x.GetType().GetProperty("requested_column").GetValue(x))
.Distinct();
I've always been a fan of "mapping" a column to an anonymous method responsible for retrieving the contents of that column:
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
Console.WriteLine("Hello World");
var items = new List<SomeObject> {new SomeObject { Age = 10, Name = "Daniel", Company = "InCycle" },
{new SomeObject { Age = 20, Name = "Not Daniel", Company = "Not InCycle" }
}};
var result = Filter<int>(items, "Age");
Console.WriteLine(result.Last());
}
public static IEnumerable<T> Filter<T>(IEnumerable<SomeObject> items, string filterCriteria)
{
var mappings = new Dictionary<string, Func<IEnumerable<SomeObject>, IEnumerable<T>>>
{
{ "Age", filterItems => filterItems.Select(item => item.Age).Distinct().Cast<T>() },
{ "Name", filterItems => filterItems.Select(item => item.Name).Distinct().Cast<T>() },
{ "Company", filterItems => filterItems.Select(item => item.Company).Distinct().Cast<T>() }
};
return mappings[filterCriteria](items);
}
}
public class SomeObject
{
public int Age {get;set;}
public string Name {get;set;}
public string Company {get; set;}
}
The downside to this approach is that if you add additional properties, you could forget to add them to the filtering. Expressions are a solid approach as well.
One way is to use a method like this.
private IList<obj1> SortListAccordingToParameter(string filter)
{
if(filter == "Name")
return objTemp.Select(x => x.Name).Distinct();
else if(filter == "Age")
return objTemp.Select(x => x.Age).Distinct();
else if(filter == "Company")
return objTemp.Select(x => x.Company).Distinct();
}
If you know the type of the property you will be searching for, you could use expressions.
string propName = "Age";
var paramExpression = Expression.Parameter(typeof(Obj1));
// o =>
var memberExpression = Expression.Property(paramExpression, propName);
// o => o.Age
var lambdaExpression = Expression.Lambda<Func<Obj1, string>>(memberExpression, paramExpression);
// (o => o.Age)
var compiled = lambdaExpression.Compile();
IList<Obj1> objTemp = new List<Obj1>();
for (var i = 0; i < 15; i++) {
Obj1 temp = new Obj1();
temp.Name = "Name" + i;
temp.Age = "Age" + i;
temp.Company = "Company" + i;
objTemp.Add(temp);
}
var results = objTemp.Select(compiled);
// equivalent to objTemp.Select(o => o.Age), plus a delegate call and the time to
// compile the lambda.
I would probably wrap this up in a static class, like this:
static class Gen<TModel, TProp> {
public static Func<TModel, TProp> SelectorExpr(string propertyName) {
var pExpr = Expression.Parameter(typeof (TModel));
var mExpr = Expression.Property(pExpr, propertyName);
var lExpr = Expression.Lambda<Func<TModel, TProp>>(mExpr, pExpr);
return lExpr.Compile();
}
}
that way you can write your selector like:
var results = objTemp.Select(Gen<Obj1, string>.SelectorExpr(propName));
That seems a bit more clear to me what it is I'm doing, especially if I'm reading expression DOM code I wrote 6 months after.
public class Test
{
public string name { get; set; }
public string age { get; set; }
public string contact { get; set; }
public Test getName(string name)
{
List<Test> testList = new List<Test>();
testList.Add(new Test { name = "Developer", age = "24", contact = "99009900990" });
testList.Add(new Test { name = "Tester", age = "30", contact = "009900990099" });
return testList.Where(c => c.name == name).FirstOrDefault();
}
}
static void Main(string[] args)
{
Test testObj = new Test();
Test selectedObj = testObj.getName("Developer");
}
Related
How do I generalize this function? I want Name property to be variable, and have function accept, replace the persons class with any class.
// Filtering logic
Func<SampleFilterModel, IEnumerable<Person>> filterData = (filterModel) =>
{
return persons.Where(p => p.Name.StartsWith(filterModel.Term ?? String.Empty, StringComparison.InvariantCultureIgnoreCase))
.Skip((filterModel.Page-1) * filter.Limit)
.Take(filterModel.Limit);
};
Other items:
IEnumerable<Person> persons = new List<Person>() {
new Person() { Name = "Laura Callahan", DOB = DateTime.Parse("1958-01-09"), Email = "laura.callahan#test.com" },
new Person() { Name = "Anne Dodsworth", DOB = DateTime.Parse("1966-01-27"), Email = "anne.dodsworth#test.com" }
};
public class SampleFilterModel
{
public int Page { get; set; }
public int Limit { get; set; }
public string Term { get; set; }
public SampleFilterModel()
{
this.Page = 1;
this.Limit = 3;
}
public object Clone()
{
var jsonString = JsonConvert.SerializeObject(this);
return JsonConvert.DeserializeObject(jsonString, this.GetType());
}
}
Current attempt, trying to modify/rework as needed:
giving some problems/errors:
Do I have to declare all variables as static?
Getting error message:
'T' does not contain a definition for 'propertyInfo' and no accessible extension method 'propertyInfo' accepting a first argument of type 'T' could be found (are you missing a using directive or an assembly reference?)
Code:
public class Filterclass<T> where T : class
{
public static string ColumnName;
public static SampleFilterModel filter = new SampleFilterModel();
public static IEnumerable<T> input;
public Func<SampleFilterModel, IEnumerable<T>> filterData = (filterModel) =>
{
var propertyInfo = input.GetType().GetProperty(ColumnName);
return input.Where(p => p.propertyInfo.StartsWith(filterModel.Term ?? String.Empty, StringComparison.InvariantCultureIgnoreCase))
.Skip((filterModel.Page - 1) * filter.Limit)
.Take(filterModel.Limit);
};
}
While the rest of the question does not make much sense to me, the part about trying to make a generic function would require building up a predicate for the Where call
Review the comments included to get an example of how to build up the lambda expression used for the predicate
public static class Filterclass {
static readonly MethodInfo startsWith = typeof(string).GetMethod("StartsWith", new[] { typeof(string), typeof(System.StringComparison) });
public static IEnumerable<T> FilterData<T>(this IEnumerable<T> input, string columnName, FilterModel filterModel) where T : class {
var type = typeof(T);
var propertyInfo = type.GetProperty(columnName);
//T p =>
var parameter = Expression.Parameter(type, "p");
//T p => p.ColumnName
var name = Expression.Property(parameter, propertyInfo);
// filterModel.Term ?? String.Empty
var term = Expression.Constant(filterModel.Term ?? String.Empty);
//StringComparison.InvariantCultureIgnoreCase
var comparison = Expression.Constant(StringComparison.InvariantCultureIgnoreCase);
//T p => p.ColumnName.StartsWith(filterModel.Term ?? String.Empty, StringComparison.InvariantCultureIgnoreCase)
var methodCall = Expression.Call(name, startsWith, term, comparison);
var lambda = Expression.Lambda<Func<T, bool>>(methodCall, parameter);
return input.Where(lambda.Compile())
.Skip((filterModel.Page - 1) * filterModel.Limit)
.Take(filterModel.Limit);
}
}
Now this assumes that the column is of type string. Any other type would cause this to throw an exception.
You would also need to assume that p is not null else again a null reference exception will be thrown when trying to call instance members on a null reference.
Sample unit test of the extension method in use
[TestClass]
public class MyTestClass2 {
[TestMethod]
public void MyTestMethod() {
//Arrange
IEnumerable<Person> persons = new List<Person>() {
new Person() { Name = "Nancy Davolio", DOB = DateTime.Parse("1948-12-08"), Email = "nancy.davolio#test.com" },
new Person() { Name = "Andrew Fuller", DOB = DateTime.Parse("1952-02-19"), Email = "andrew.fuller#test.com" },
new Person() { Name = "Janet Leverling", DOB = DateTime.Parse("1963-08-30"), Email = "janet.leverling#test.com" },
new Person() { Name = "Margaret Peacock", DOB = DateTime.Parse("1937-09-19"), Email = "margaret.peacock#test.com" },
new Person() { Name = "Steven Buchanan", DOB = DateTime.Parse("1955-03-04"), Email = "steven.buchanan#test.com" },
new Person() { Name = "Michael Suyama", DOB = DateTime.Parse("1963-07-02"), Email = "michael.suyama#test.com" },
new Person() { Name = "Robert King", DOB = DateTime.Parse("1960-05-29"), Email = "robert.king#test.com" },
new Person() { Name = "Laura Callahan", DOB = DateTime.Parse("1958-01-09"), Email = "laura.callahan#test.com" },
new Person() { Name = "Anne Dodsworth", DOB = DateTime.Parse("1966-01-27"), Email = "anne.dodsworth#test.com" }
};
var filter = new FilterModel {
Term = "Nancy"
};
//Act
var data = persons.FilterData("Name", filter);
//Assert
data.Should().NotBeEmpty();
}
}
I am trying to apply the predicate not only to the entity parent but also to the child collection. The following is part of my code:
var predicate = PredicateBuilder.New<Entity>();
foreach (string keyword in keywords)
{
string temp = keyword;
predicate = predicate.Or(p => p.Name.Equals(temp));
predicate = predicate.Or(p => p.Addresses.Select(x=> x.Name.Equals(temp));
}
The line predicate = predicate.Or(p => p.Addresses.Select(x=> x.Name.Equals(temp)); is not working ? any ideas as to why?
EDIT
In the following demo I am asking to get entity parent and child with name = tom but I also get child name = tom2.
private static void Main(string[] args)
{
var result = GetAll(GetAll(), new List<string> { "tom" });
}
private static List<User> GetAll()
{
return new List<User>
{
new User
{
Id = 1,
Name = "tom",
Addesses = new List<Addesses>
{
new Addesses { Id = 1, Name = "tom" },
new Addesses { Id = 1, Name = "tom2" },
}
},
new User
{
Id = 1,
Name = "sam",
Addesses = new List<Addesses>
{
new Addesses { Id = 1, Name = "sam" },
new Addesses { Id = 1, Name = "sam2" },
}
},
};
}
private static List<User> GetAll(List<User> users, List<string> keywords)
{
var predicate = PredicateBuilder.New<User>();
foreach (string keyword in keywords)
{
string temp = keyword;
predicate = predicate.Or(p => p.Name.Equals(temp));
predicate = predicate.Or(p => p.Addesses.Any(x => x.Name.Equals(temp)));
}
var result = users
.Where(predicate)
.ToList();
return result;
}
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public List<Addesses> Addesses { get; set; }
}
public class Addesses
{
public int Id { get; set; }
public string Name { get; set; }
}
The call to p.Addresses.Select(x=> x.Name.Equals(temp) is not returning a boolean result.
Depending on your actual logic you may want to look into Any:
predicate = predicate.Or(p => p.Addresses.Any(x=> x.Name.Equals(temp));
or All:
predicate = predicate.Or(p => p.Addresses.All(x=> x.Name.Equals(temp));
I have an EF class that looks like this:
public class Item
public string ItemId{ get; set; }
public string NormalDescription { get; set; }
public string LongDescription { get; set; }
public string ShortDescription { get; set; }
.. <snip>
In addition, I have a DTO that looks like this:
public class ItemDTO
public string Id { get; set; }
public string DisplayName { get; set; }
.. <snip>
Upon loading the data from the 'Item' class into the DTO, I need to conditionally set 'DisplayName' based on a configuration setting. In other words, I'm looking for something similar to:
return _repo.GetAsQueryable<Item>()
.Select(i=> new ItemDTO
{
Id = i.ItemId,
DisplayName = (setting == 1) ? i.NormalDescription :
(setting == 2) ? i.LongDescription :
(setting == 3) ? i.ShortDescription :
String.Empty
}
Of course, this results in some very inefficient SQL (using 'CASE' to evaluate each possible value) being sent to the database. This is a performance issue as there's a TON of description fields on the Item.
That being said, is there a way to select ONLY the field that's required to populate the 'DisplayName' value?
In other words, instead of a query filled with 'CASE WHEN' logic, I'd like to ONLY retrieve one of the Description values based on my application configuration setting.
You should create lambda Expression dynamically:
var typeOfItem = typeof(Item);
var argParam = Expression.Parameter(typeOfItem, "x");
var itemIdProperty = Expression.Property(argParam, "ItemId");
var properties = typeOfItem.GetProperties();
Expression descriptionProperty;
if (setting < properties.Count())
descriptionProperty = Expression.Property(argParam, properties[setting].Name);
else
descriptionProperty = Expression.Constant(string.Empty);
var ItemDTOType = typeof(ItemDTO);
var newInstance = Expression.MemberInit(
Expression.New(ItemDTOType),
new List<MemberBinding>()
{
Expression.Bind(ItemDTOType.GetMember("Id")[0], itemIdProperty),
Expression.Bind(ItemDTOType.GetMember("DisplayName")[0], descriptionProperty),
}
);
var lambda = Expression.Lambda<Func<Item, ItemDTO>>(newInstance, argParam);
return _repo.GetAsQueryable<Item>().Select(lambda);
Something like this?
var repo = _repo.GetAsQueryable<Item>();
if (setting == 1)
{
return repo.Select(i => new ItemDTO
{
Id = i.ItemId,
DisplayName = i.NormalDescription
});
}
if (setting == 2)
{
return repo.Select(i => new ItemDTO
{
Id = i.ItemId,
DisplayName = i.LongDescription
});
}
if (setting == 3)
{
return repo.Select(i => new ItemDTO
{
Id = i.ItemId,
DisplayName = i.ShortDescription
});
}
return repo.Select(i => new ItemDTO
{
Id = i.ItemId,
DisplayName = String.Empty
});
EDIT
You can create the expression dynamically as Slava Utesinov showed. If you do not want to build the whole expression, you can replace just the parts you want:
public class UniRebinder : ExpressionVisitor
{
readonly Func<Expression, Expression> replacement;
UniRebinder(Func<Expression, Expression> replacement)
{
this.replacement = replacement;
}
public static Expression Replace(Expression exp, Func<Expression, Expression> replacement)
{
return new UniRebinder(replacement).Visit(exp);
}
public override Expression Visit(Expression p)
{
return base.Visit(replacement(p));
}
}
Expression<Func<Item, ItemDTO>> ReplaceProperty(
int setting, Expression<Func<Item, ItemDTO>> value)
{
Func<MemberExpression, Expression> SettingSelector(int ss)
{
switch (ss)
{
case 1: return x => Expression.MakeMemberAccess(x.Expression, typeof(Item).GetProperty(nameof(Item.NormalDescription)));
case 2: return x => Expression.MakeMemberAccess(x.Expression, typeof(Item).GetProperty(nameof(Item.LongDescription)));
case 3: return x => Expression.MakeMemberAccess(x.Expression, typeof(Item).GetProperty(nameof(Item.ShortDescription)));
default: return x => Expression.Constant(String.Empty);
}
}
return (Expression<Func<Item, ItemDTO>>)UniRebinder.Replace(
value,
x =>
{
if (x is MemberExpression memberExpr
&& memberExpr.Member.Name == nameof(Item.NormalDescription))
{
return SettingSelector(setting)(memberExpr);
}
return x;
});
}
private void Test()
{
var repo = (new List<Item>() {
new Item() {
ItemId ="1",
LongDescription = "longd1",
NormalDescription = "normald1",
ShortDescription = "shortd1" },
new Item() {
ItemId ="2",
LongDescription = "longd2",
NormalDescription = "normald2",
ShortDescription = "shortd2" }
}).AsQueryable();
for (int selector = 1; selector < 5; ++selector)
{
var tst = repo.Select(ReplaceProperty(selector,
i => new ItemDTO
{
Id = i.ItemId,
DisplayName = i.NormalDescription
})).ToList();
Console.WriteLine(selector + ": " + string.Join(", ", tst.Select(x => x.DisplayName)));
//Output:
//1: normald1, normald2
//2: longd1, longd2
//3: shortd1, shortd2
//4: ,
}
}
I am working on code which will give Cartesian product of two anonymous types. These 2 anonymous types are generated from database.
Code for 1st anonymous type:
private IEnumerable<object> GetItem()
{
return _unitOfWork.GetRepository<Item>()
.ListAll()
.Select(x => new
{
itemId = x.Id,
itemName = x.Name
})
}
Code for 2nd anonymous type:
private IEnumerable<object> GetVenue()
{
return _unitOfWork.GetRepository<Venue>()
.ListAll()
.Select(x => new
{
locationName = x.Address.City,
venueId = x.VenueId,
venueName = x.Name
})
}
I have following method to get the data and perform Cartesian product and return the data.
public object GetRestrictLookupInfo(IEnumerable<int> lookupCombinations)
{
IEnumerable<object> restrictList = new List<object>();
if (lookupCombinations.Contains(1))
{
var tempProductProfileList = GetItem();
restrictList = tempProductProfileList.AsEnumerable();
}
if (lookupCombinations.Contains(2))
{
var tempProductGroupList = GetVenue();
restrictList = (from a in restrictList.AsEnumerable()
from b in tempProductGroupList.AsEnumerable()
select new { a, b });
}
return restrictList;
}
I have controller which calls this method and return data in json format.
Controller Code
public HttpResponseMessage GetData(IEnumerable<int> lookupCombinations)
{
var lookupRestrictInfo = _sellerService.GetRestrictLookupInfo(lookupCombinations);
return Request.CreateResponse(HttpStatusCode.OK, lookupRestrictInfo);
}
Response expected is:-
[ {
"itemId": 1,
"itemName": "Music",
"locationName": "Paris",
"venueId": 99,
"venueName": "Royal Festival Hall"
} ]
Response which I receive is
[ {
"a": {
"itemId": 1,
"itemName": "Music"
},
"b": {
"locationName": "Paris",
"venueId": 99,
"venueName": "Royal Festival Hall" } }]
I am not able to get the expected JSON string.
You should start with the simplest possible code that shows your problem; your code above has a lot of complexities that may (or may not) have anything to do with your problem. Is this about manipulating anonymous types? Doing a Cartesian product with LINQ? Converting an object to JSON?
Here's one possible answer to what you might be looking for; notice that you can pass around anonymous types using generics instead of object.
namespace AnonymousTypes
{
class Program
{
static string Serialize(object o)
{
var d = (dynamic)o;
return d.ItemId.ToString() + d.ItemName + d.VenueId.ToString() + d.LocationName + d.VenueName;
}
static string GetData<T>(IEnumerable<T> result)
{
var retval = new StringBuilder();
foreach (var r in result)
retval.Append(Serialize(r));
return retval.ToString();
}
static string GetRestrictLookupInfo()
{
var restrictList = new[] { new { Id = 1, Name = "Music" }, new { Id = 2, Name = "TV" } };
var tempProductGroupList = new[] { new { LocationName = "Paris", Id = 99, Name = "Royal Festival Hall" } };
var result = from item in restrictList
from venue in tempProductGroupList
select new
{
ItemId = item.Id,
ItemName = item.Name,
LocationName = venue.LocationName,
VenueId = venue.Id,
VenueName = venue.Name
};
return GetData(result);
}
public static string GetData()
{
return GetRestrictLookupInfo();
}
static void Main(string[] args)
{
var result = GetData();
}
}
}
If that's not what you're looking for, you might start with code that doesn't use anonymous types, such as
namespace AnonymousTypes
{
sealed class Item
{
public int Id { get; set; }
public string Name { get; set; }
}
sealed class Venue
{
public string LocationName { get; set; }
public int Id { get; set; }
public string Name { get; set; }
}
sealed class ItemAndVenue
{
public int ItemId { get; set; }
public string ItemName { get; set; }
public string LocationName { get; set; }
public int VenueId { get; set; }
public string VenueName { get; set; }
}
class Program
{
static IEnumerable<Item> GetItem()
{
return new[] { new Item { Id = 1, Name = "Music" } };
}
static IEnumerable<Venue> GetVenue()
{
return new[] { new Venue { LocationName = "Paris", Id = 99, Name = "Royal Festival Hall" } };
}
static IEnumerable<ItemAndVenue> GetRestrictLookupInfo()
{
var restrictList = GetItem();
var tempProductGroupList = GetVenue();
var result = from item in restrictList
from venue in tempProductGroupList
select new ItemAndVenue
{
ItemId = item.Id,
ItemName = item.Name,
LocationName = venue.LocationName,
VenueId = venue.Id,
VenueName = venue.Name
};
return result;
}
static string GetData()
{
var v = GetRestrictLookupInfo().First();
return v.ItemId.ToString() + v.ItemName + v.VenueId.ToString() + v.LocationName + v.VenueName;
}
static void Main(string[] args)
{
var result = GetData();
}
}
}
In order to produce a single item in the output you need to create a new type, named or anonymous. Since you are using objects rather than actual types, the quickest approach is to cast them to dynamic:
var tempProductGroupList = GetVenue();
restrictList = (from a in restrictList.Cast<dynamic>()
from b in tempProductGroupList.Cast<dynamic>()
select new {
itemId = (int)a.itemId,
itemName = (string)a.itemName,
locationName = (string)b.locationName,
venueId = (int)b.venueId,
venueName = (string)b.venueName
});
This code is tightly coupled to the code producing both lists, because it assumes the knowledge of the field names of types passed into it dynamically. Any change in the structure of source data must be followed by a change in the code making combinations. In addition, it defeats run-time checking, so you need to be very careful with this code.
Try to create a simple object instead of nesting:
select new { a.itemId, a.itemName, b.locationName }
Like an option:
public object GetRestrictLookupInfo(IEnumerable<int> lookupCombinations)
{
List<Dictionary<string, object>> result = new List<Dictionary<string, object>>();
if (lookupCombinations.Contains(1))
{
var tmp = _unitOfWork.GetRepository<Item>()
.ListAll()
.Select(x => new
{
itemId = x.Id,
itemName = x.Name
})
.Select(x =>
{
var dic = new Dictionary<string, object>();
dic.Add(nameof(x.itemId), x.itemId);
dic.Add(nameof(x.itemName), x.itemName);
return dic;
});
result.AddRange(tmp);
}
if (lookupCombinations.Contains(2))
{
var tmp = _unitOfWork.GetRepository<Venue>()
.ListAll()
.Select(x => new
{
locationName = x.Address.City,
venueId = x.VenueId,
venueName = x.Name
})
.Select(x =>
{
var dic = new Dictionary<string, object>();
dic.Add(nameof(x.locationName), x.locationName);
dic.Add(nameof(x.venueId), x.venueId);
dic.Add(nameof(x.venueName), x.venueName);
return dic;
});
result = result.SelectMany(r => tmp.Select(t => r.Concat(t)));
}
return result;
}
It looks like some magic. I uses dictionary instead of object. It can be make in more clear way (extract few methods), but the idea should be clear.
Then, during serialization it will be presented as you need.
Maybe this is a duplicate thread, but I am going to try, because there is a tiny difference.
I am trying to build a dynamic expression to filter a collection property.
The code:
public class TestEntity
{
public int ID { get; set; }
public string Name { get; set; }
public IEnumerable<string> Values { get; set; }
}
public class TestFilter
{
public TestFilter()
{
var itens = new List<TestEntity>();
itens.Add(new TestEntity { ID = 1, Name = "Test1", Values = new List<string> { "V1", "V2" } });
itens.Add(new TestEntity { ID = 2, Name = "Test2", Values = new List<string> { "V6", "V3" } });
itens.Add(new TestEntity { ID = 3, Name = "Test3", Values = new List<string> { "V4", "V5" } });
itens.Add(new TestEntity { ID = 4, Name = "Test4", Values = new List<string> { "V2", "V3" } });
itens = itens.Where(e => e.Values.Any(c => c.Equals("V2"))).ToList();
**//Result IDs: 1, 4**
}
}
The filter above will give me IDs 1 and 4 as result.
I want to filter entities where exists a certain value in the collection "Values".
So far, I have tried this thread, but didnt realize how it can be done.
Any help would be apreciated.
So you are seeking for a method which given a collection property name and value will produce Where predicate like e => e.Collection.Any(c => c == value).
You can use the following extension method (hope the code is self explanatory):
public static class QueryableExtensions
{
public static IQueryable<T> WhereAnyEquals<T>(this IQueryable<T> source, string collectionName, object value)
{
var e = Expression.Parameter(typeof(T), "e");
var collection = Expression.PropertyOrField(e, collectionName);
var itemType = (collection.Type.IsIEnumerableT() ? collection.Type :
collection.Type.GetInterfaces().Single(IsIEnumerableT))
.GetGenericArguments()[0];
var c = Expression.Parameter(itemType, "c");
var itemPredicate = Expression.Lambda(
Expression.Equal(c, Expression.Constant(value)),
c);
var callAny = Expression.Call(
typeof(Enumerable), "Any", new Type[] { itemType },
collection, itemPredicate);
var predicate = Expression.Lambda<Func<T, bool>>(callAny, e);
return source.Where(predicate);
}
private static bool IsIEnumerableT(this Type type)
{
return type.IsInterface && type.IsConstructedGenericType &&
type.GetGenericTypeDefinition() == typeof(IEnumerable<>);
}
}
like this:
itens = itens.AsQueryable().WhereAnyEquals("Values", "V2").ToList();
If you step through the code, the variable predicate contains the expression you are asking for.