【问题标题】:Bitwise flag in ORMLiteORMLite 中的按位标志
【发布时间】:2017-07-23 11:55:19
【问题描述】:

我的 db 表中有一个按位标志列,我想选择没有特定标志的行。例如,我想检索未停用的客户列表。

我用 ORMLite 写这个

var q = db.Select<Customer>().where(c => (c.Flags & CustomerFlag.Deactive) != CustomerFlag.Deactive);

但是当我看到 ORMLite 在调试中生成的查询时,'&' 变成了 'AND'。 所以我得不到我想要的。

我也使用了 HasFlag。但是ORMLite似乎不支持它。

有人有解决办法吗?

ps:数据库是 SQLite

【问题讨论】:

    标签: c# linq sqlite lambda ormlite


    【解决方案1】:

    这在 OrmLite 中没有实现。单个 AND &amp; 甚至有效的事实是巧合。

    查看源here,向下滚动到这个方法:

    protected virtual string BindOperant(ExpressionType e)
    

    switch 语句列出了转换为 SQL 运算符的二元运算符。请注意,列表中缺少ExpressionType.And;只有ExpressionType.AndAlso 存在。

    因此,ExpressionType.And 属于default 的情况:

    default:
        return e.ToString();
    

    这与返回AND 相同,SQL 将其解释为逻辑AND

    没有解决此问题的方法。

    由于该项目的源代码是免费提供的,因此您可以提交此问题的修复程序。解决方案可能很简单,只需将这四行添加到SqlExpression.cs 文件中的switch 语句即可:

    case ExpressionType.And:
        return "&";
    case ExpressionType.Or:
        return "|";
    

    【讨论】:

    • 非常感谢您的回答,是的,您说得对,不幸的是它没有在 ORMLite 中实现。但我找到了另一种解决方案。看来我们也可以编写原始 SQL 条件。所以当我回答我自己的问题时,我用原始 SQL 处理了这个 Bit-wise 部分。
    • @Azade 我没有办法验证这一点,但很有可能在SqlExpression.cs 文件中添加两行可以解决问题。请看一看。
    【解决方案2】:

    我讨厌回答我自己的问题。但似乎我终于找到了答案。如果有人遇到同样的问题,我会写下来以提供帮助。

    实际上,我将 lambda 的“按位”部分替换为原始 sql 代码:

    var q = db.Select<Customer>().Where($"(Flags & {(int)CustomerFlag.Deactive} != {(int)CustomerFlag.Deactive}");
    

    所以生成的查询是这样的:

    select * from customer where (flag & 8) <> 8
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-18
      • 1970-01-01
      • 2014-09-19
      • 2013-10-18
      相关资源
      最近更新 更多