C# 用于从数据库检索筛选器值的重构方法

C# 用于从数据库检索筛选器值的重构方法,c#,entity-framework,linq-to-sql,refactoring,C#,Entity Framework,Linq To Sql,Refactoring,我正在使用.NETFramework4、MVC3和EntityFramework(最新版本) 在索引页上,我希望能够过滤每一列。LINQ使用distinct()方法检索每个列的筛选器值。我还没有找到一个好方法来重用为每个列检索这些值的方法-它们基本上是相等的,唯一区别它们的是使用的列名,因此使用一个方法而不是多个方法将是非常好的 public List<string> GetLevels() { return _db.Logs.Select(l => l.Level).

我正在使用.NETFramework4、MVC3和EntityFramework(最新版本)

在索引页上,我希望能够过滤每一列。LINQ使用distinct()方法检索每个列的筛选器值。我还没有找到一个好方法来重用为每个列检索这些值的方法-它们基本上是相等的,唯一区别它们的是使用的列名,因此使用一个方法而不是多个方法将是非常好的

public List<string> GetLevels()
{
    return _db.Logs.Select(l => l.Level).Distinct().ToList();
}

public List<string> GetOrders()
{
    return _db.Logs.Select(l => l.Order).Distinct().ToList();
}
公共列表GetLevels()
{
return _db.Logs.Select(l=>l.Level.Distinct().ToList();
}
公共列表GetOrders()
{
return _db.Logs.Select(l=>l.Order.Distinct().ToList();
}
如何使用要从中检索数据的列名注入lambda表达式?大概是这样的:

public List<string> GetFilterValues(string columName)
{
    return _db.Logs.Select(l => l.columnName).Distinct.ToList();
}
公共列表GetFilterValue(字符串列名)
{
return _db.Logs.Select(l=>l.columnName).Distinct.ToList();
}

您可以编写一个函数,该函数采用一个表达式来选择所需的属性:

public List<T> GetLogProperties<T>(Expression<Func<Log, T>> selector)
{
    return _db.Logs.Select(selector).Distinct().ToList();
}

public List<string> GetLevels()
{
    return GetLogProperties(l => l.Level);
}
public List GetLogProperties(表达式选择器)
{
返回_db.Logs.Select(selector).Distinct().ToList();
}
公共列表GetLevels()
{
返回GetLogProperties(l=>l.Level);
}
编辑:如果要从字符串列创建投影,则必须自己构建表达式:

public List<string> GetFilterValues(string columnName)
{
    var paramExpr = Expression.Parameter(typeof(Log), "l");
    var propExpr = Expression.Property(paramExpr, columnName);
    var lambdaExpr = Expression.Lambda<Func<Log, string>>(propExpr, paramExpr);

    return _db.Logs.Select(lambdaExpr).Distinct().ToList();
}

List<string> levels = GetFilterValues("Level");
public List GetFilterValues(string columnName)
{
var parametexpr=Expression.Parameter(typeof(Log),“l”);
var propExpr=Expression.Property(paramExpr,columnName);
var lambdaExpr=Expression.Lambda(propExpr,paramExpr);
返回_db.Logs.Select(lambdaExpr.Distinct().ToList();
}
列表级别=GetFilterValue(“级别”);

请注意,如果具有给定名称的属性不是
字符串
属性,则会引发异常。

您可以编写一个函数,该函数使用表达式选择所需的属性:

public List<T> GetLogProperties<T>(Expression<Func<Log, T>> selector)
{
    return _db.Logs.Select(selector).Distinct().ToList();
}

public List<string> GetLevels()
{
    return GetLogProperties(l => l.Level);
}
public List GetLogProperties(表达式选择器)
{
返回_db.Logs.Select(selector).Distinct().ToList();
}
公共列表GetLevels()
{
返回GetLogProperties(l=>l.Level);
}
编辑:如果要从字符串列创建投影,则必须自己构建表达式:

public List<string> GetFilterValues(string columnName)
{
    var paramExpr = Expression.Parameter(typeof(Log), "l");
    var propExpr = Expression.Property(paramExpr, columnName);
    var lambdaExpr = Expression.Lambda<Func<Log, string>>(propExpr, paramExpr);

    return _db.Logs.Select(lambdaExpr).Distinct().ToList();
}

List<string> levels = GetFilterValues("Level");
public List GetFilterValues(string columnName)
{
var parametexpr=Expression.Parameter(typeof(Log),“l”);
var propExpr=Expression.Property(paramExpr,columnName);
var lambdaExpr=Expression.Lambda(propExpr,paramExpr);
返回_db.Logs.Select(lambdaExpr.Distinct().ToList();
}
列表级别=GetFilterValue(“级别”);

请注意,如果具有给定名称的属性不是
string
属性,这将引发异常。

与其在一个方法中完成所有操作,不如将以下属性设置为:
public List GetLevels{get{return}db.Logs.Select(l=>l.Level).Distinct().ToList();}
这样更可读。顺便问一下,为什么你想在一种方法中有两种不同的东西?我确信返回值会有所不同。@PLB,我同意,它更可读。我仍然想知道是否有可能将列名注入表达式中。是的,答案包含解决方案,但如果使用一个,则意味着每次调用该方法时,都必须传递表达式,这似乎不是一个好主意。与其在一个方法中完成所有操作,如果您将属性设置为:
publicslist GetLevels{get{return}db.Logs.Select(l=>l.Level.Distinct().ToList();}}
这样会更具可读性。顺便问一下,为什么你想在一种方法中有两种不同的东西?我确信返回值会有所不同。@PLB,我同意,它更可读。我仍然想知道是否有可能将列名注入表达式中。是的,答案包含解决方案,但如果您使用一个,则意味着每次调用该方法时,您都必须传递表达式,这似乎不是一个好主意。我更喜欢您的第一个示例的简单性。我喜欢您的第一个例子更好。