如何遍历 Odata 实体模型图?

How do I walk the Odata entity model graph?

#r "nuget: Microsoft.OData.Edm"

open Microsoft.OData.Edm
open System.Xml

let reader = XmlReader.Create("metadata.xml")
let success, edmModel, errors  = Csdl.CsdlReader.TryParse(reader)

let container = edmModel.EntityContainer
let elements = edmModel.SchemaElements |> Seq.cast<IEdmSchemaElement> |> Array.ofSeq

for elem in elements do
    printfn $"1  {elem.Name} : {elem.SchemaElementKind} : {elem.Location()}"

let entitySets = container.EntitySets() |> Seq.cast<IEdmEntitySet> |> Array.ofSeq

for elem in entitySets do
    let cElems = elem.Container.Elements |> Seq.cast<IEdmEntityContainerElement> |> Array.ofSeq
    printfn $"   2  {elem.Name} : {elem.ContainerElementKind}"

    for celem in cElems do
        printfn $"      3  {celem.Name} : {celem.ContainerElementKind}"

这是我可以使用 Microsoft.OData.Edm 遍历 odata 实体模型图的程度。 2级和3级打印的结果是一样的。我想访问实体类型的键和属性。

我总是可以切换到遍历 XML 图,但使用维护的 odata 库似乎是正确的做法。

我认为这里的技巧是尽可能将元素向下转换为 IEdmEntityType

let entTypes =
    edmModel.SchemaElements
        |> Seq.choose (function
            | :? IEdmEntityType as entType -> Some entType
            | _ -> None)
for entType in entTypes do
    printfn "%s" entType.Name
    for prop in entType.DeclaredProperties do
        printfn "   %s %s" prop.Name (prop.Type.ShortQualifiedName())

输出类似于:

Product
   ID Int32
   Name String
   Description String
   ReleaseDate DateTimeOffset
   DiscontinuedDate DateTimeOffset
   Rating Int16
   Price Double
   Categories
   Supplier ODataDemo.Supplier
   ProductDetail ODataDemo.ProductDetail
FeaturedProduct
   Advertisement ODataDemo.Advertisement
ProductDetail
   ProductID Int32
   Details String
   Product ODataDemo.Product