Entity Framework / Linq - get various values ​​of a dynamically set property

I have a requirement to get a list of different values ​​for specific properties of a collection of objects.

So, let table A have fields x, y, z, 1, 2, 3, where x is PK (thus, outside the table).

I need to get all the unique values ​​for y, z, 1, 2, or 3, without knowing in my method which field I get. Thus, the template for the method will look like this:

public List<ObjectName> GetUniqueFieldValues(string fieldname) 

An ObjectName is an object with two properties that the above method populates at least one property for each result.

Someone in another question had a similar answer using the ParameterExpression and Expression classes, but in fact they did not provide enough information to help me with my specific task.

I was also looking for reflection, but of course Linq doesn't really like the Select statement.

I would just use it, if I call it good, but there is really a ton of fields / properties in a real table / object, so this is impractical. It will also save me some refactoring if the base table ever changes.

SQL version of what I'm trying to do:

 SELECT Distinct [usersuppliedfieldname] from TableName where [someotherconditionsexist] 

The pseudocode of what I already have:

 public List<ReturnObject> GetUniqueFieldValues(int FkId, ConditionObject searchmeta) { using(DbEntities db = new DbEntities()) { // just getting the basic set of results, notice this is "Select *" var results = from f in db.Table where f.FkId == FkId && [some static conditions] select f; // filtering the initial results by some criteria in the "searchmeta" object results = ApplyMoreConditions(results, searchmeta); // GOAL - Select and return only distinct field(s) specified in searchmeta.FieldName) } } 
+4
source share
1 answer

You can try something like this (similar to a message that was suggested as a duplicate)

 public static class DynamicQuerier { private delegate IQueryable<TResult> QueryableMonad<TInput, TResult>(IQueryable<TInput> input, Expression<Func<TInput, TResult>> mapper); public static IQueryable<TResult> Select<TInput, TResult>(this IQueryable<TInput> input, string propertyName) { var property = typeof (TInput).GetProperty(propertyName); return CreateSelector<TInput, TResult>(input, property, Queryable.Select); } private static IQueryable<TResult> CreateSelector<TInput, TResult>(IQueryable<TInput> input, MemberInfo property, QueryableMonad<TInput, TResult> method) { var source = Expression.Parameter(typeof(TInput), "x"); Expression propertyAccessor = Expression.MakeMemberAccess(source, property); var expression = Expression.Lambda<Func<TInput, TResult>>(propertyAccessor, source); return method(input, expression); } } 

For my test, I created a dummy set of objects called Tests , below is a request to get various values ​​from Property2

 var values = context.Tests.Select<Test, int>("Property2").Distinct(); 
+2
source

Source: https://habr.com/ru/post/1497842/


All Articles