使用实体框架时为Select()创建通用选择器

时间:2019-06-27 11:04:30

标签: c# entity-framework linq select lambda

我想创建一个函数来检索给定属性名称的类型的列表。但是我还不知道如何创建一个工作的lambda选择器。

public IList<object> GetDistinctListOfProperty(string propertyName)
{
    var propInfoByName = typeof(T).GetProperty(propertyName);
    if (propInfoByName == null) return new List<object>();

    using (var db = new ApplicationDbContext())
    {
        var lambda = //TODO
        return db.Set<T>().Select(lambda).Distinct().ToList();
    }
}

2 个答案:

答案 0 :(得分:4)

您可以使用此方法生成lambda

guard let context = (UIApplication.shared.delegate as? AppDelegate)?.persistentContainer.viewContext else {
    return
}

do {
    let fetchRequest : NSFetchRequest<Todo> = Todo.fetchRequest()
    fetchRequest.predicate = NSPredicate(format: "completed == 1")
    let fetchedResults = try context.fetch(fetchRequest) as? [NSManagedObject]
    fetchedResults.forEach { context.delete($0) }
    try context.save()
}
catch {
    print("Error with request: \(error)")
}

然后使用此方法创建您的表达式

public static Expression<Func<T, object>> LambdaGenerator<T>(string propertyName)
    {
        var arg = Expression.Parameter(typeof(T), "current");
        var property = Expression.Property(arg, propertyName);
        var conv = Expression.Convert(property, typeof(object));
        var exp = Expression.Lambda<Func<T, object>>(conv, new ParameterExpression[] { arg });
        return exp;
    }

答案 1 :(得分:2)

您可以为此使用表达式:

private IList<Tout> GetDistinctListOfProperty<Ttable, Tout>(Expression<Func<Ttable, Tout>> returnField) where Ttable : class
{
    using (var db = new ApplicationDbContext())
    {
        return db.Set<Ttable>().Select(returnField).Distinct().ToList();
    }
}

您需要将Func包装到Expression中,以便实体可以将其转换为有效的sql。该版本允许您在选择参数时使用智能感知。您会这​​样称呼它:

var result = GetDistinctListOfProperty<YourTableType>(x => x.YourProperty);

此版本将适用于您的ApplicationDbContext已知的每个表