在通用 DbSet 查询中使用 Distinct

Using Distinct in generic DbSet queries

我正在尝试 运行 针对 Entity Framework DbSet 的不同查询。这些列表用于填充 UI 中的选择以过滤 TRecord 的数据集。下面列出了完整的方法。 fieldNameDbSet 中的字段之一。下面的代码有效但效率低下。如果您尝试直接在 DbSet 上使用 Distinct(),它不会进行区分 - 只是 returns 完整数据集。我假设问题在于我使用反射获取值的方式。有解决办法吗?

public async static Task<List<string>> GetDistinctListAsync<TRecord>(this DbContext context, string fieldName) where TRecord : class, IDbRecord<TRecord>, new()
{
     // Get the DbSet for TRecord
     var dbset = GetDbSet<TRecord>(context, null);
     // declare list as an empty list
     var list = new List<string>();
     // Get the filter propertyinfo object
     var x = typeof(TRecord).GetProperty(fieldName);
     if (dbset != null && x != null)
     {
          // we get the full list and then run a distinct because we can't run a distinct directly on the dbSet
          var fulllist = await dbset.Select(item => x.GetValue(item).ToString()).ToListAsync();
          list = fulllist.Distinct().ToList();
     }
     return list ?? new List<string>();
}

我正在修改我的旧代码,该代码使用了通过 DbSet.FromSQLRaw().

调用的 SQL 不同查询

请注意,我不知道魔法 GetDbSet<TRecord> 有什么作用,这里有一个替代函数可以处理它,灵感来自:

public static async Task<List<string>> GetDistinctListAsync<TRecord>(this DAL.DbContext context, string fieldName) where TRecord : class
    {
        var dbset = context.Set<TRecord>();

        // Return value.
        List<string> list = null;

        if (dbset != null) // Found matching dbSet
        {
            // Convert our property into a lambda expression.
            var arg = Expression.Parameter(typeof(TRecord), "current");
            var property = Expression.Property(arg, fieldName);
            var conv = Expression.Convert(property, typeof(object));
            var exp = Expression.Lambda<Func<TRecord, object>>(conv, new ParameterExpression[] { arg });

            list = 
                (await dbset.Select(exp).Distinct().ToArrayAsync()) // This runs against database / SQL
                .Select(x => x.ToString()).ToList(); // Convert return values into strings locally if necessary.
        }
        return list ?? new List<string>();
    }