【问题标题】:Filling a DataTable with two(or more) joined tables用两个(或更多)连接表填充 DataTable
【发布时间】:2014-04-09 21:04:18
【问题描述】:

我有两个要加入并用于填充数据表的表,但我遇到了列名冲突问题:

-----------    -----------
| Parent  |    | Child   |
-----------    -----------
| ParentID|    | ChildID |
| Name    |    | ParentID|
| Value   |    | Name    |
-----------    | Value   | 
               -----------

SQL 语句(MySQL 数据库,以防相关)

select p.*, c.* from parent p left join child c on c.ParentID = c.ChildID

我的适配器代码(C#):

var adapter = new MySqlDataAdapter(sql, DBConn);
adapter.Fill(table);

当我去阅读这些行时,我希望是这样的:

var parentName = row["p.Name"];
var childName = row["c.Name"];

相反,结果是这样的:

var parentName = row["Name"];
var childName = row["Name1"];

如何让列名使用别名?我觉得我遗漏了一些明显的东西,因为这似乎应该一直出现。

【问题讨论】:

  • Hey Norm,如果我们帮助了您,您应该选择一个答案! :) 如果您还没有投票,请点赞。
  • 是的,Rafas 的答案解决了这个特定的情况,但是有一个一般用例没有。从下面开始:这不是我“拥有”别名的问题,而是从代码中删除特殊情况。我宁愿给所有东西起别名,而不仅仅是一些东西。如果我不能想出更好的东西,他的回答会问我问的问题,所以我会接受。
  • 我认为对所有内容都使用别名是正确的方法。如果您正在生成 sql,则在每列中附加 "as " + tablename + "_" + columnname 之类的内容可以解决您的所有问题,并且代码非常清晰。
  • 另外,@Rafas 的答案是第一个,所以他没有理由不应该得到答案。这是一个伟大的,我赞成他。然而,表面上,我们说的是同一件事。
  • 同意,我只希望有一个“选择 p.tablename_*”,所以我不必明确命名所有列。不过,我可以使用生成器来构建构建 sql 的东西,这意味着我不必手动将其全部写出来,至少

标签: c# mysql dataadapter


【解决方案1】:

由于name 是两个表的通用列名,因此您必须在查询中为其中任何一个指定一个别名。如果您不提供一个,它将自动为重复的字段提供一个,在这种情况下附加一个“1”。

此外,c.p. 只是查询的内部别名,但它们不构成返回列名的一部分。

在您的 SQL 查询中输入别名(至少其中一个)

SELECT p.name as parent_name, c.name as child_name, ….

并且在您的 C# 代码中使用正确的列

var parentName = row["parent_name"];
var childName = row["child_name"];

【讨论】:

  • 有没有办法做一个表范围的前缀?实际的表有很多列,必须单独为每列设置别名很麻烦。
  • 您只需为那些具有相同名称的那些别名。此外,使用.* 进行选择也不是一个好主意,因为这会导致数据库首先(内部)执行额外查询以查找列名。
  • 这不是我“拥有”别名的问题,而是从代码中删除特殊情况。如果我可以将表范围的前缀传递给选择(比如选择 p.Parent_*,我知道这不是一件事),那么我可以使该前缀成为一个变量,在编写续集和处理行。我的模型有很多表,与通用解决方案相比,每次存在列名冲突时都必须编写特殊情况是没有吸引力的。我宁愿给所有东西起别名,而不仅仅是一些东西。
【解决方案2】:

每当您处理 sql 字符串时,写出所有字段名称而不是使用 *

总是一个很好的约定

在这种情况下,您的问题是您的查询中有两次 name,因此它会在其后自动填充 1 以消除歧义。

试试这个:

select
    p.ParentId,
    p.Name as parent_name,
    p.Value as parent_value
    c.ChildId,
    c.Name as child_name,
    c.Value as child_value
from parent p left join child c on p.ParentID = c.ChildID

您的 c# 代码也需要反映这一点。

var parentName = row["parent_name"];
var childName = row["child_name"];

【讨论】:

  • 只是一个错字问题 - 你有 c.ParentID = c.ChildID 它应该是 p.parentId = c.childId
  • @EvanL 谢谢,OP 的列名全部大写,而我的是小写。现在应该是正确的。
  • 嗯...我认为您不能对同一张表中的两列进行连接。他有parent p left join child c on c.parentId = c.childId,你也有。它真的应该是p.parentId。真的是在吹毛求疵,我还是给你 +1 了;)
  • 眼睛好?不...每天有太多的SQL?是的;)
【解决方案3】:

查询中的别名是为了让mysql知道你的意思,如果你想在输出中使用唯一的列名

Select p.Name as ParentName, c.Name as ChildName .... etc

我当然不会依赖 Name1 胡言乱语,将您的查询更改为 select c.*, p.*,事情就会变得很糟糕。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-15
    • 2014-05-22
    • 2015-11-20
    • 2016-01-09
    • 2010-12-13
    • 2020-12-15
    相关资源
    最近更新 更多