【问题标题】:Convert Yes/No/Null from SQL to True/False in a DataTable将 SQL 中的 Yes/No/Null 转换为 DataTable 中的 True/False
【发布时间】:2011-01-31 19:04:39
【问题描述】:

我有一个 Sql 数据库(我无法控制架构),它的 Column 的 varchar 值为“是”、“否”,否则将为空。出于我所做的目的,null 将被视为否。

我正在使用数据表和表适配器在 c# net 3.5 中进行编程,以将数据拉下。我想使用绑定源将列直接绑定到程序中的复选框,但是我不知道如何或在何处放置将字符串 Yes/No/null 转换为布尔 True/False 的逻辑;

从 SQL 服务器读取 null 并在更新时写回 No 是可接受的行为。

非常感谢任何帮助。

编辑—— 这是为 Windows 开发的。

【问题讨论】:

  • 你正在开发什么应用程序 windows,asp.net 或 silverlight?
  • 我认为数据绑定很重要。更改 select 语句很容易,但这个问题似乎包括数据绑定,可以正确写回 YesNo 到数据库。

标签: c# sql sql-server datatable


【解决方案1】:

如果您可以修改用于检索数据的 SQL,请执行类似的操作。

Select isnull(MyColumn,'No') as MyColumn

【讨论】:

  • 啊抱歉,重新阅读您的问题并注意我的错误。上面 Dathan 的回答应该更适合。
【解决方案2】:

修改填充DataTable 的查询以包含适当的逻辑:

SELECT col1, col2, CAST(CASE YesNoNullCol WHEN 'yes' THEN 1 WHEN 'no' THEN 0 ELSE 0 END AS BIT) FROM SomeTable

编辑:忘记了您还必须在 DataAdapter 上提供插入/更新/删除命令。

为了使用上述方法使提交生效,您需要指定自定义命令来执行数据库更新:

SqlCommand insert_cmd = connection.CreateCommand();
insert_cmd.CommandText = "INSERT INTO SomeTable(col1, col2, YesNoNullCol) VALUES (@col1, @col2, CASE @yesnonullcol WHEN 1 THEN 'Yes' WHEN 0 THEN 'No' ELSE 'No' END)";
var yesno_col = insert_cmd.CreateParameter();
yesno_col.Name = "@yesnonullcol";
insert_cmd.Parameters.Add(col1_parm);
myAdapter.InsertCommand = insert_cmd;

当然,您还需要为@col1@col2 提供参数。如果你想支持这些操作,你需要创建更新和删除命令。

【讨论】:

  • 这是最简单的部分。他需要能够正确写回数据库“是”和“否”的数据绑定。
  • 如果我把它放在填充它的查询中,选择工作正常,但更新不包括更改。
  • @Scott apologies - 我已经更新了问题(虽然,再次道歉,我没有编译代码,我只是写了它,所以可能存在语法或逻辑错误)。
  • 我确实最喜欢您的解决方案,但我在解决另一个问题的同时找到了更好的方法。
  • @Scott 很公平。您应该发布您的其他方式作为解决方案并接受它,这样任何搜索类似问题的人都可以从该答案中受益。
【解决方案3】:

这很容易完成,无需先修改数据。您可以直接绑定到您的复选框,然后在 DataBindings |高级您可以指定空值的用途。

抱歉,我没有注意到您需要转换 varchar Yes 和 No。Dathan 的回答将正确获取您的数据,但我很确定您将不得不使用自定义保存方法手动更新值。

【讨论】:

  • 但是如何将字符串“是”和“否”绑定到布尔值,以便与高级菜单中的选中属性绑定?
【解决方案4】:

这段代码将字符串转换为布尔值?可以使用的。 Nullabe 类型有一个“HasValue”属性,指示它们是否为空。

public bool TryParseNullableBool (string value, out bool? result)
{
  result = false;
  if (string.IsNullOrEmpty (value))
  {
    result = null;
    return true;
  }
  else
  {
    bool r;
    if (bool.TryParse (value, out r))
    {
      result = r;
      return true;
    }
  }
  return false;
}

【讨论】:

  • 我喜欢它,我可以将该逻辑放在 RowChanged 事件中进行加载,我可以对写入执行相反的操作。
  • 我会避开这种方法 - 不是因为它不起作用(它显然可以),而是因为它会将持久性存储工件泄漏到业务逻辑中。只要有可能,您应该尝试让您的 IO 逻辑负责从数据模型转换为对象模型。实现上述内容似乎是一个很小的牺牲(在这种情况下确实如此),但它的扩展性并不好。如果在您的业务逻辑中,您总是将该字段用作布尔值,那么它应该在暴露于业务逻辑的每个点都是布尔值。
【解决方案5】:

我最初使用 Dathan 的解决方案,但是我的复选框不会将其更新推送到它所绑定的数据表,同时尝试解决我发现的关于 Binding.ParseBinding.Format 的问题我现在让查询正常并使用这个:

Public Form1()
{
    InitializeComponent();
    cbxKeepWebInfinityChanges.DataBindings["Checked"].Parse += new ConvertEventHandler(cbxKeepWebInfinityChanges_Parse);
    cbxKeepWebInfinityChanges.DataBindings["Checked"].Format += new ConvertEventHandler(cbxKeepWebInfinityChanges_Format);
}

void cbxKeepWebInfinityChanges_Parse(object sender, ConvertEventArgs e)
{
    if ((bool)e.Value == true)
        e.Value = "Yes";
    else
        e.Value = "No";
}
void cbxKeepWebInfinityChanges_Format(object sender, ConvertEventArgs e)
{
    if ((string)e.Value == "Yes")
        e.Value = true;
    else
        e.Value = false;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-08
    • 2013-09-09
    • 1970-01-01
    • 2010-10-11
    • 2011-04-09
    • 2011-08-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多