简体   繁体   English

实体框架/ Linq - 获取动态指定属性的不同值

[英]Entity Framework / Linq - Get distinct values of dynamically specified property

I have a requirement to get the list of distinct values for specific properties of a collection of entities. 我需要获取实体集合的特定属性的不同值列表。

So, let's say table A has fields x, y, z, 1, 2, 3 where x is the PK(thus off the table). 所以,假设表A有字段x,y,z,1,2,3,其中x是PK(因此离开表格)。

I need to get all the unique values for y, z, 1, 2, or 3, without necessarily knowing in my method which field I'm getting. 我需要获得y,z,1,2或3的所有唯一值,而不必在我的方法中知道我正在获得哪个字段。 So the pattern for the method would be: 所以该方法的模式是:

public List<ObjectName> GetUniqueFieldValues(string fieldname)

The "ObjectName" object is an object with two properties, which the method above will fill at least one property per result. “ObjectName”对象是具有两个属性的对象,上述方法将为每个结果填充至少一个属性。

Someone in another question had a similar answer using the ParameterExpression and Expression classes but didn't really provide enough information to help me with my specific task. 另一个问题中的某个人使用ParameterExpression和Expression类得到了类似的答案,但实际上没有提供足够的信息来帮助我完成我的具体任务。

I also tried reflection but of course Linq does not like that very much within a Select expression. 我也尝试过反射,但当然Linq在Select表达式中并不那么喜欢。

I would just use if and call it good but there are really a ton of fields/properties in the actual table/object so it's impractical. 我会使用if并称之为好,但实际的表/对象中确实存在大量的字段/属性,因此它不切实际。 This would also save me a little refactoring if the base table ever changes. 如果基表发生变化,这也可以节省一些重构。

SQL version of what I'm trying to do: 我正在尝试做的SQL版本:

SELECT Distinct [usersuppliedfieldname] from TableName where [someotherconditionsexist]

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)

    }
}

You might try something like this (similar to the post that was suggested as 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've created a dummy set of entities called Tests , below is the query to get the distinct values from the Property2 对于我的测试,我创建了一组称为Tests的虚拟实体,下面是从Property2获取不同值的查询

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM