在通用 DbSet 查询中使用 Distinct
Using Distinct in generic DbSet queries
我正在尝试 运行 针对 Entity Framework DbSet
的不同查询。这些列表用于填充 UI 中的选择以过滤 TRecord
的数据集。下面列出了完整的方法。 fieldName
是 DbSet
中的字段之一。下面的代码有效但效率低下。如果您尝试直接在 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>();
}
我正在尝试 运行 针对 Entity Framework DbSet
的不同查询。这些列表用于填充 UI 中的选择以过滤 TRecord
的数据集。下面列出了完整的方法。 fieldName
是 DbSet
中的字段之一。下面的代码有效但效率低下。如果您尝试直接在 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()
.
请注意,我不知道魔法 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>();
}