【问题标题】:NHibernate mapping from dtd or xsd or even xml document itself来自 dtd 或 xsd 甚至 xml 文档本身的 NHibernate 映射
【发布时间】:2016-11-20 00:48:05
【问题描述】:

我已经搜索和搜索,但找不到任何与答案相似的东西。

我有一个用于 XML 文档类型(我的文档类型,与 NHibernate 无关)的 DTD (xml-dtd),我想将该给定文档类型的所有文档存储到一个关系模型中。不,我不想将 XML 文件本身作为某种 varchar 或 XML 字段或诸如此类的东西存储到数据库中,这违背了目的 - 我想将其分解为其元素和属性并存储它,作为适当的关系模型。 XML 支持这一点。

我可以在 Visual Studio 2015 中从给定的 DTD 创建一个 XSD,然后使用该 XSD 创建反映给定 XSD(以及扩展原始 DTD)的 C# 类。文档解析,一切正常。

现在的问题是如何通过 NHibernate 将这些 XML 文档存储到 RDBMS 中,而无需(大量)手工编码,从而所有关系都以这种方式呈现?必须有一种简单的方法来使用自动映射功能,但是原始 DTD 有一些“限制”(一些 IDREF 的东西等等,关系的东西),我想动态地“转换”成关系并拥有适当的与其他类的关系,而不是将“代码”存储为字符串类型的值。

所以基本上,我同时需要一位 NHibernate && XML && DTD && XSD 大师来阐明如何轻松实现这一点。至少在过去的 10 到 15 年里,我 100% 确定这种事情在休眠和休眠中是“正常的”(我从未尝试过,似乎是我第一次需要将 XML 文档存储在分解的数据库中到它们的组成部分而不是整体)。

如果这样的事情是不可能的,那么 NHibernate 是否有“XML 文档驱动程序”这样的东西,这样它就不必进入 RDBMS 而是作为 XML 文档保留在文件系统上?

示例(对于那里的 SGML/XML 专家,请查看 IDREF 和 NMTOKEN,为什么它们“只是”字符串而不是与它们应该去哪里的适当关系,即另一个类或用法或变体或其他什么?): 最终结果:

我希望引用是带有“代码”(或 id)G117 本身的“类”(如 public virtual Class Reference { get; set; }

实际结果:只是一个字符串“code”,其值为“G117”,如

    [System.Xml.Serialization.XmlAttributeAttribute(DataType="NMTOKEN")]
    public string code {
        get {
            return this.codeField;
        }
        set {
            this.codeField = value;
        }
    }

XML 文件:

<Class code="G117" kind="process">
    <SuperClass code="G"/>
    <Rubric id="13-223" kind="preferred">
        <Label xml:lang="en">A preferred label</Label>
    </Rubric>
    <Rubric id="13-224" kind="shortTitle">
        <Label xml:lang="en">Short title</Label>
    </Rubric>
    <Rubric id="13-225" kind="exclusion">
        <Label xml:lang="en">There is some exclusion text with a reference here <Reference>G12</Reference></Label>
    </Rubric>
    <Rubric id="13-226" kind="criteria">
        <Label xml:lang="en">Some criteria text goes here</Label>
    </Rubric>
</Class>

<Rubric id="56-327" kind="exclusion">
    <Label xml:lang="en">This is some thext that might refer someplace <Reference>G117</Reference>; and another piece of text that refers to another place <Reference>BF9</Reference>; Another text describing something and there might be a reference from this piece of text somewhere else too <Reference>AB7</Reference></Label>
</Rubric>

DTD:

<!ELEMENT Class (Meta*,SuperClass*,SubClass*,ModifiedBy*,ExcludeModifier*,Rubric*,History*)>
<!ATTLIST Class code NMTOKEN #REQUIRED kind IDREF #REQUIRED usage IDREF #IMPLIED variants IDREFS #IMPLIED>
<!ELEMENT Rubric (Label+,History*)>
<!ATTLIST Rubric id ID #IMPLIED kind IDREF #REQUIRED usage IDREF #IMPLIED>
<!ELEMENT Reference (#PCDATA)>
<!ATTLIST Reference classCode CDATA #IMPLIED authority NMTOKEN #IMPLIED uid NMTOKEN #IMPLIED code NMTOKEN #IMPLIED usage IDREF #IMPLIED variants IDREFS #IMPLIED>

生成的 XSD:

  <xs:element name="Class">
    <xs:complexType>
      <xs:sequence>
        <xs:element minOccurs="0" maxOccurs="unbounded" ref="Meta" />
        <xs:element minOccurs="0" maxOccurs="unbounded" ref="SuperClass" />
        <xs:element minOccurs="0" maxOccurs="unbounded" ref="SubClass" />
        <xs:element minOccurs="0" maxOccurs="unbounded" ref="ModifiedBy" />
        <xs:element minOccurs="0" maxOccurs="unbounded" ref="ExcludeModifier" />
        <xs:element minOccurs="0" maxOccurs="unbounded" ref="Rubric" />
        <xs:element minOccurs="0" maxOccurs="unbounded" ref="History" />
      </xs:sequence>
      <xs:attribute name="code" type="xs:NMTOKEN" use="required" />
      <xs:attribute name="kind" type="xs:IDREF" use="required" />
      <xs:attribute name="usage" type="xs:IDREF" />
      <xs:attribute name="variants" type="xs:IDREFS" />
    </xs:complexType>
  </xs:element>
  <xs:element name="Rubric">
    <xs:complexType>
      <xs:sequence>
        <xs:element minOccurs="1" maxOccurs="unbounded" ref="Label" />
        <xs:element minOccurs="0" maxOccurs="unbounded" ref="History" />
      </xs:sequence>
      <xs:attribute name="id" type="xs:ID" />
      <xs:attribute name="kind" type="xs:IDREF" use="required" />
      <xs:attribute name="usage" type="xs:IDREF" />
    </xs:complexType>
  </xs:element>
  <xs:element name="Reference">
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base="xs:string">
          <xs:attribute name="classCode" type="xs:string" />
          <xs:attribute name="authority" type="xs:NMTOKEN" />
          <xs:attribute name="uid" type="xs:NMTOKEN" />
          <xs:attribute name="code" type="xs:NMTOKEN" />
          <xs:attribute name="usage" type="xs:IDREF" />
          <xs:attribute name="variants" type="xs:IDREFS" />
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>

生成的 C# 类

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://tempuri.org/MyStuff")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://tempuri.org/MyStuff", IsNullable=false)]
public partial class Class {

    private Meta[] metaField;

    private SuperClass[] superClassField;

    private SubClass[] subClassField;

    private ModifiedBy[] modifiedByField;

    private ExcludeModifier[] excludeModifierField;

    private Rubric[] rubricField;

    private History[] historyField;

    private string codeField;

    private string kindField;

    private string usageField;

    private string variantsField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("Meta")]
    public Meta[] Meta {
        get {
            return this.metaField;
        }
        set {
            this.metaField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("SuperClass")]
    public SuperClass[] SuperClass {
        get {
            return this.superClassField;
        }
        set {
            this.superClassField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("SubClass")]
    public SubClass[] SubClass {
        get {
            return this.subClassField;
        }
        set {
            this.subClassField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("ModifiedBy")]
    public ModifiedBy[] ModifiedBy {
        get {
            return this.modifiedByField;
        }
        set {
            this.modifiedByField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("ExcludeModifier")]
    public ExcludeModifier[] ExcludeModifier {
        get {
            return this.excludeModifierField;
        }
        set {
            this.excludeModifierField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("Rubric")]
    public Rubric[] Rubric {
        get {
            return this.rubricField;
        }
        set {
            this.rubricField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("History")]
    public History[] History {
        get {
            return this.historyField;
        }
        set {
            this.historyField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute(DataType="NMTOKEN")]
    public string code {
        get {
            return this.codeField;
        }
        set {
            this.codeField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute(DataType="IDREF")]
    public string kind {
        get {
            return this.kindField;
        }
        set {
            this.kindField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute(DataType="IDREF")]
    public string usage {
        get {
            return this.usageField;
        }
        set {
            this.usageField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute(DataType="IDREFS")]
    public string variants {
        get {
            return this.variantsField;
        }
        set {
            this.variantsField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://tempuri.org/MyStuff")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://tempuri.org/MyStuff", IsNullable=false)]
public partial class Rubric {

    private Label[] labelField;

    private History[] historyField;

    private string idField;

    private string kindField;

    private string usageField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("Label")]
    public Label[] Label {
        get {
            return this.labelField;
        }
        set {
            this.labelField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("History")]
    public History[] History {
        get {
            return this.historyField;
        }
        set {
            this.historyField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute(DataType="ID")]
    public string id {
        get {
            return this.idField;
        }
        set {
            this.idField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute(DataType="IDREF")]
    public string kind {
        get {
            return this.kindField;
        }
        set {
            this.kindField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute(DataType="IDREF")]
    public string usage {
        get {
            return this.usageField;
        }
        set {
            this.usageField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://tempuri.org/MyStuff")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://tempuri.org/MyStuff", IsNullable=false)]
public partial class Reference {

    private string classCodeField;

    private string authorityField;

    private string uidField;

    private string codeField;

    private string usageField;

    private string variantsField;

    private string valueField;

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string classCode {
        get {
            return this.classCodeField;
        }
        set {
            this.classCodeField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute(DataType="NMTOKEN")]
    public string authority {
        get {
            return this.authorityField;
        }
        set {
            this.authorityField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute(DataType="NMTOKEN")]
    public string uid {
        get {
            return this.uidField;
        }
        set {
            this.uidField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute(DataType="NMTOKEN")]
    public string code {
        get {
            return this.codeField;
        }
        set {
            this.codeField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute(DataType="IDREF")]
    public string usage {
        get {
            return this.usageField;
        }
        set {
            this.usageField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute(DataType="IDREFS")]
    public string variants {
        get {
            return this.variantsField;
        }
        set {
            this.variantsField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlTextAttribute()]
    public string Value {
        get {
            return this.valueField;
        }
        set {
            this.valueField = value;
        }
    }
}

【问题讨论】:

    标签: xml nhibernate xsd nhibernate-mapping fluent-nhibernate-mapping


    【解决方案1】:

    我很困惑——你似乎在自相矛盾。有一次您说“如何通过 NHibernate 将这些 XML 文档存储到 RDBMS 中?”过了一会儿,你问“NHibernate 是否有“XML 文档驱动程序”这样的东西,这样它就不必进入 RDBMS,而是作为 XML 文档保留在文件系统上?这似乎与第一个问题完全相反。

    无论如何 - NHibernate 是一个框架,用于在对象模型和可以使用 SQL 查询的各种关系数据库系统之间进行映射。如果你发现一个使用 XML 文件存储数据并向这些文件公开 SQL 外观的 RDBMS,也许你可以为此编写一个 NHibernate 驱动程序,但 NHibernate 本身肯定不包含任何针对 XML 文件的查询引擎。

    至于使用 NHibernate 将其映射到 RDBMS,我怀疑您最好的选择是编写一些东西来生成 NHibernate 的映射配置。通过转换为 NHibernate 的 XML 配置,或者通过为 Mapping-By-Code 或 FluentNHibernate 发出代码。

    【讨论】:

    • 我忘了说“万一这样的事情是不可能的,那么……”
    • 编辑并添加了“万一这样的事情是不可能的,那么”,希望你批准编辑?
    【解决方案2】:

    好吧,Oskar 和其他可能对这样的事情感兴趣的人,我花了 12 天的时间,但最后我确实弄明白了,并且成功了。创建映射、数据库并用来自 xml 的数据填充它需要几秒钟(可能是 2 秒钟),但它工作得很好。仍然不确定如何将“IDREF”类型映射到真实 ID,但与我过去几天的经历相比,这是一个小问题。

    【讨论】:

      猜你喜欢
      • 2019-10-25
      • 1970-01-01
      • 2010-09-06
      • 2012-02-07
      • 2013-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-23
      相关资源
      最近更新 更多