简体   繁体   中英

F# Navigate object graph to return specific Nodes

I'm trying to build a list of DataTables based on DataRelations in a DataSet, where the tables returned are only included by their relationships with each other, knowing each end of the chain in advance. Such that my DataSet has 7 Tables. The relationships look like this:

Table1 -> Table2 -> Table3 -> Table4 -> Table5
                           -> Table6 -> Table7

So given Table1 and Table7, I want to return Tables 1, 2, 3, 6, 7

My code so far traverses all the relations and returns all Tables so in the example it returns Table4 and Table5 as well. I've passed in the first, last as arguments, and know that I'm not yet using the last one yet, I am still trying to think how to go about it, and is where I need the help.

type DataItem =
    | T of DataTable
    | R of DataRelation list

let GetRelatedTables (first, last) =
    let rec flat_rec dt acc =
        match dt with
        | T(dt)   -> 
            let rels = [ for r in dt.ParentRelations do yield r ]
            dt :: flat_rec(R(rels)) acc             
        | R(h::t) -> 
            flat_rec(R(t)) acc @ flat_rec(T(h.ParentTable)) acc
        | R([])   -> []
    flat_rec first []

I think something like this would do it (although I haven't tested it). It returns DataTable list option because, in theory, a path between two tables might not exist.

let findPathBetweenTables (table1 : DataTable) (table2 : DataTable) =
    let visited = System.Collections.Generic.HashSet() //check for circular references
    let rec search path =
        let table = List.head path
        if not (visited.Add(table)) then None
        elif table = table2 then Some(List.rev path)
        else 
            table.ChildRelations
            |> Seq.cast<DataRelation>
            |> Seq.tryPick (fun rel -> search (rel.ChildTable::path))
    search [table1]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM