【问题标题】:How to do dynamic comparison in Linq to SQL with a string field?如何在 Linq to SQL 中使用字符串字段进行动态比较?
【发布时间】:2013-01-12 06:01:48
【问题描述】:

如何在 Linq to SQL 中使用字符串字段进行动态比较以获得如下查询:

"SELECT COLUMN_1, COLUMN_2" +
"FROM "+ stringTABLE +
"WHERE " + stringCOLUMN_1_or2  + " = ' " + 8 + "'";

我知道我可以这样做:

from x in objects
where x.COLUMN_1 == "8"
select x

但 FIELD 是可变的,可以是 COLUMN_1 或 COLUMN_2" 或其他...

作为我想在 Windows 窗体(框架 4.0)中执行的操作的示例

from x in objets
where x.field[stringCOLUMN_1_or2] == "8"
select x

我该怎么做? 提前谢谢

【问题讨论】:

  • 看来你想要linq to sql dynamicstackoverflow.com/questions/697345/…
  • where x.field[stringCOLUMN_1] == " 8" -- 但我不完全确定我是否听懂了你的问题
  • 注意:...COLUMN_2" + "FROM... 产生无效查询。 (还有 ...stringTABLE + "WHERE ... 除非 stringTABLE 以 ' ' 结尾。
  • 我想做一些类似动态比较但没有太多代码的事情
  • 您如何知道使用哪一列进行比较?

标签: c# .net winforms entity-framework-4 linq-to-entities


【解决方案1】:

通常,LINQ to SQL 将创建一个与您的列同名的属性,因此您的 LINQ 可能如下所示:

from x in objets
where x.stringCOLUMN_1 == 8.ToString()
select x;

【讨论】:

  • 那不是x.COLUMN_1吗? (Linq 不知道他用什么变量来创建查询......)
  • 我只是离开提供的实际 SQL 查询。 SQL server 中列的名称是什么并不完全清楚。
  • FIELD 是变量,可以是 COLUMN_1 或 COLUMN_2" 或其他... stringCOLUMN 是包含列名称的字符串变量
【解决方案2】:

不确定什么是对象,或者你的字段集合,但如果是字符串比较,首先你应该在文字周围加上引号:

from x in objets
where x.field[stringCOLUMN_1] == "8"
select x

通常您的列名表示为属性。

from x in objets
where x.stringCOLUMN_1 == "8"
select x

最后,通常你有一个 DBContext,你需要深入它来选择一个特定的表:

from x in db.TableNameHere
where x.stringCOLUMN_1 == "8"
select x

如果没有看到代码的更多上下文,就很难提供更多建议。

如果您希望做一些更动态的事情,请注意您可以使用扩展方法附加额外的 where 条件:

var query = from x in db.TableNameHere select x;
if(ShouldFilterColumn1)
  query = query.Where(x => x.Column1 == "8");

var results = query.ToList();

如果没有看到代码的更多上下文,就很难提供更多建议。

【讨论】:

    【解决方案3】:

    我能想到三种可能性。

    第一个是动态 LINQ。我调查过一次,但没有走多远。

    第二个选项(类似于 AaronLS 的建议)是一次构建查询。这是我最常使用的选项。
    注意:您必须在 select 或 order 子句之前添加 where 子句,否则运行时会出现异常。

    var query = from x in objects;
    switch (columnIndicator)
    {
        case ColumnIndicatorTypes.Column1:
            query = query.Where(x => x.Column1 == "8");
            break;
        case ColumnIndicatorTypes.Column2:
            query = query.Where(x => x.Column2 == "8");
            break;
        case ColumnIndicatorTypes.Column3:
            query = query.Where(x => x.Column3 == "8");
            break;
        case ColumnIndicatorTypes.Column4:
            query = query.Where(x => x.Column4 == "8");
            break;
    }
    

    第三个选项是编码所有选项。例如:

    switch (columnIndicator)
    {
        case ColumnIndicatorTypes.Column1:
            query = from x in objects
                where x.COLUMN_1 == "8"
                select x;
            break;
        case ColumnIndicatorTypes.Column2:
            query = from x in objects
                where x.COLUMN_2 == "8"
                select x;
            break;
        case ColumnIndicatorTypes.Column3:
            query = from x in objects
                where x.COLUMN_3 == "8"
                select x;
            break;
        case ColumnIndicatorTypes.Column4:
            query = from x in objects
                where x.COLUMN_4 == "8"
                select x;
            break;
        default:
            query = from x in objects
                select x;
            break;
    }
    

    如果您想查看生成的查询,我建议在运行查询之前连接到db.Log(类似于db.Log = New System.IO.StringWriter(New StringBuilder())),在您的服务器上运行探查器(例如 SQL Server Profiler),或者将对象转换为一个字符串(我认为这会返回查询的字符串版本,但已经有一段时间了)。

    【讨论】:

      【解决方案4】:

      你可以使用ExpressionTree来做到这一点

      How to: Use Expression Trees to Build Dynamic Queries (C# and Visual Basic)

      Create predicate with nested classes with Expression,其中Marc Gravell's answer 看起来简单可行。

      更新: 在 LinqToSql 的情况下,上面的链接没有帮助。

      查看 Trisped 答案(第二个选项),它可能会有所帮助。

      【讨论】:

      • 我目前正在 .net 4.0 中测试 Marc Gravell 的答案。有没有可能它不再工作了,或者他期待.net 4.5? (Where() 想要在我的系统上使用 Func<> 而不是 Expression<>
      • 非常抱歉,这无济于事。这些示例适用于 Linq To Entities。
      【解决方案5】:

      我猜你可以使用反射:

      from x in db.TableName
          where (x.GetType().GetProperty(stringCOLUMN_1_or2).GetValue(x, null)) == " 8"
          select x;
      

      不确定是否有任何简单的 Linqish 方法可以做到这一点......

      编辑:假设动态 Linq 可以工作,那就是:

      from x in objets
      .Where(stringCOLUMN_1_or2  + " = ' " + 8 + "'")
      select x
      

      这里有一些关于使用 SQL 的动态 Linq 的更多信息:http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

      【讨论】:

      • 如何在 SQL 脚本中翻译?
      • @AlexanderBalte 这不取决于 Linq to SQL 引擎吗?我想这取决于 x 的属性是占位符还是临时对象中的数据值。
      • 您不能在 LinqToSql 语句中进行反思。甚至String.IsNullOrEmpty
      • @AlexanderBalte 好的,所以这只适用于 Linq,而不适用于 Linq to SQL。
      • in x.GetType().GetProperty("COLUMN_2") 为空...无法进行比较
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-17
      • 1970-01-01
      • 2011-07-10
      相关资源
      最近更新 更多