【问题标题】:C# Linq Query on database using field name as a variable使用字段名称作为变量的数据库上的 C# Linq 查询
【发布时间】:2014-01-16 18:04:52
【问题描述】:

这是我的代码。谁能帮我重构这段代码。我正在尝试使用字段名称作为变量,所以我不必使用 switch case。来自dr in db.Users where dr.FieldName.Contains(value) 的东西。

public static List<User> GetUser(string value, string fieldName)
{
    var db = new CCPTDataContext();
    var users = new List<User>();

    switch (fieldName)
    {
        case "FirstName":
            users = (from dr in db.Users where dr.FirstName.Contains(value)
                     select new User
                     {
                         Username = dr.Username,
                         FirstName = dr.FirstName,
                         LastName = dr.LastName
                     }).ToList();

            break;
        case "LastName":
            users = (from dr in db.Users where dr.LastName.Contains(value)
                     select new User
                     {
                         Username = dr.Username,
                         FirstName = dr.FirstName,
                         LastName = dr.LastName
                     }).ToList();
            break;
    }
    return users;
}

【问题讨论】:

标签: c# database linq variables


【解决方案1】:

您必须使用 System.Linq.Expression 命名空间中的类手动创建表达式树:

public static Expression<Func<TSource, bool>> GetPropertyContainsValueExpression<TSource>(string propertyName, string value)
{
    var param = Expression.Parameter(typeof(TSource), "x");
    var prop = Expression.Property(param, propertyName);
    var valueExp = Expression.Constant(value, typeof(string));
    var contains = Expression.Call(prop, "Contains", null, valueExp);
    return Expression.Lambda<Func<TSource, bool>>(contains, param);
}

那么你可以这样使用它:

public static List<User> GetUser(string value, string fieldName)
{
    var db = new CCPTDataContext();

    return db.Users.Where(GetPropertyContainsValueExpression<User>(fieldName, value)).ToList();
}

【讨论】:

  • 某些提供程序(我认为是 EF 5)可能无法正确参数化上述 sn-p 中的查询。为了获取参数化查询,我所做的是将值包装在 Tuple 中并获取 Item1 属性:var container = new Tuple&lt;string&gt;(value); var containerExpression = Expression.Constant(container, typeof(Tuple&lt;string&gt;)); var valueExp = Expression.Property(containerExpression, "Item1");
  • @Kosar 不客气!如果它解决了您的问题,您应该考虑将答案标记为已接受。这就是 SO 的工作原理!
  • @Marcin,我试图标记为已接受,但找不到任何链接、按钮或类似的东西。你能指导我如何做到这一点。
  • @Kosar 在帖子评分的正下方,应该是灰色标记,您可以点击。这是一个很好的问题:meta.stackexchange.com/questions/5234/…
【解决方案2】:

这应该可行:

users = (from dr in db.Users 
where (fieldName.Equals("FirstName") && dr.FirstName.Contains(value))
      || (fieldName.Equals("LastName") && dr.LastName.Contains(value))
                 select new User
                 {
                     Username = dr.Username,
                     FirstName = dr.FirstName,
                     LastName = dr.LastName
                 }).ToList();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-12
    • 2011-03-28
    • 2012-08-14
    相关资源
    最近更新 更多