3

假设我在内存中有 5 个表模式作为 DataTables,另一个 DataTable 是其他 5 个表之间的引用约束的模式。

这 5 个模式表是相关的,因此表 A 包含与 B 中的外键相关的主键列。B 还包含与 C 中的外键列相关的主键列,以及 C 到 D,但假设 A,B, C 和 D 与 E 没有直接或间接的关系。

什么样的函数会接收两个数据表并返回一个布尔值,指示这些表是相关的还是“链接的”。

我想要完成的事情

假设我在拖放式界面中向用户展示了 5 个表中的所有列。我希望用户能够以图形方式构建查询,但我需要根据它们是否甚至可以在同一个选择语句中返回来启用/禁用某些列。

4

3 回答 3

1

您说您有第六个表,其中包含其他表之间的约束。

假设您可以有效地使用此信息,并且仅尝试映射直接关系,您可能会执行以下操作:

  • 编译可能包含可能从其他表引用的主键的所有表的列表
  • 遍历每个这样的表 X
    • 编译 X可能相关的表列表 L
    • 对于表 X 中的每个主键 K,遍历 L 中的每个表,搜索对 K 的任何引用。
    • 一旦遇到对任何 K 的引用,就中断并跳到 L 中的下一个表
    • 以某种方式存储有关关系的信息(例如,每个表 X 的 L 中的表列表)

我知道这是非常高级和抽象的,但我希望它有意义..

这可能需要一些时间来运行,具体取决于表的数量和它们关系的复杂性,但我看不出有更好的选择。

您可以将有关“禁止”关系的信息存储在例如字典中,其中包含每个表的键和列表;像这样的东西(对于单向关系,以避免重复注册信息):

{TableA => {TableB, TableC}, 
 TableB => {TableC, TableD}, 
 TableC => {}, 
 etc..}
于 2012-08-14T14:48:04.160 回答
0

如果表存在于数据集中,则数据集还可能包含您可以迭代的Datarelations 。

但是,您的数据库提供程序在加载数据时没有填充数据集中的数据关系的可能性很高。

恐怕您必须要求数据库获取关系信息。那是高度依赖数据库和数据库提供者的。

您可以查看mygeneration mymetaNHibernate的来源,了解如何做到这一点。

于 2012-08-14T15:11:35.133 回答
-1
// we have not defined which argument is the "parent" and which is the "child"
public bool IsTableRelated(DataTable thisOne, DataTable thatOne) {

    bool thisToThat = DiveDive(thisOne.Constraints, thatOne);
    bool thatToThis = DiveDive(thatOne.Constraints, thisOne);

    return thisToThat || thatToThis;
}


public bool DiveDive(ConstraintsCollection constraints, DataTable target) {

    bool theyRelate = false;

    foreach (Constraint aConstraint in constraints){

        if (aConstraint is ForeignKeyConstraint) {
            if(aConstraint.Table.TableName == target.TableName) {
                theyRelate = true;
                break;  // quit while we're ahead.
            }else{
               theyRelate = DiveDive(aConstraint.Table.Constraints, target);
            }
        } 
    }

    return theyRelate;
}
于 2012-08-14T17:21:51.047 回答