/// <summary> /// Visitor implementation. Adds code to InitClass and InitVars methods of the DataTable classes. /// </summary> /// <param name="element"></param> public override void Visit(VisitableElementComplexType element) { // The base visitor will initialize the variables. base.Visit(element); if (!IsDataSet) { string xpath; ArrayList fieldsref = new ArrayList(); ArrayList fieldskey = new ArrayList(); CodeMemberMethod initclass = RetrieveMethod(CurrentDataSetType, "InitClass"); CodeMemberMethod initvars = RetrieveMethod(CurrentDataSetType, "InitVars"); #region Initialize InitVars method. //this.tablepublishers = ((publishersDataTable)(this.Tables["publishers"])); initvars.Statements.Add( new CodeAssignStatement( new CodePropertyReferenceExpression( new CodeThisReferenceExpression(), "table" + element.Name), new CodeCastExpression(element.Name + Configuration.CollectionNaming, new CodeIndexerExpression( new CodePropertyReferenceExpression( new CodeThisReferenceExpression(), "Tables"), new CodeExpression[] { new CodePrimitiveExpression(element.Name) })))); //if ((this.tablepublishers != null)) this.tablepublishers.InitVars(); initvars.Statements.Add( new CodeConditionStatement( new CodeBinaryOperatorExpression( new CodePropertyReferenceExpression( new CodeThisReferenceExpression(), "table" + element.Name), CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)), new CodeStatement[] { new CodeExpressionStatement( new CodeMethodInvokeExpression( new CodePropertyReferenceExpression( new CodeThisReferenceExpression(), "table" + element.Name), "InitVars", new CodeExpression[0])) })); #endregion #region Initialize InitClass method. //this.tablepublishers = new publishersDataTable(); initclass.Statements.Add( new CodeAssignStatement( new CodePropertyReferenceExpression( new CodeThisReferenceExpression(), "table" + element.Name), new CodeObjectCreateExpression( element.Name + Configuration.CollectionNaming, new CodeExpression[0]))); //this.Tables.Add(this.tablepublishers); initclass.Statements.Add( new CodeMethodInvokeExpression( new CodePropertyReferenceExpression( new CodeThisReferenceExpression(), "Tables"), "Add", new CodeExpression[] { new CodePropertyReferenceExpression( new CodeThisReferenceExpression(), "table" + element.Name) })); #endregion #region Retrieve keyref nodes. xpath = ".//"; xpath += RetrievePrefix(); xpath += element.Name; xpath = "//xsd:keyref[xsd:selector/@xpath=\"" + xpath + "\"]"; XmlNodeList keyrefs = CurrentSchemaDom.SelectNodes(xpath, Namespaces); foreach (XmlNode keyref in keyrefs) { string parentname = String.Empty; string fkname = keyref.Attributes.GetNamedItem("name").Value; if (keyref.Attributes.GetNamedItem("ConstraintName") != null) { fkname = keyref.Attributes.GetNamedItem("ConstraintName").Value; } // Retrieve fields which form the keyref foreach (XmlNode node in keyref.ChildNodes) { if (node.LocalName == "field") { fieldsref.Add(Regex.Replace(node.Attributes.GetNamedItem("xpath").Value, "([A-z|0-9]+):", "")); } } //Retrieve the key being referenced and its fields xpath = ".//xsd:key[@name=\"" + keyref.Attributes.GetNamedItem("refer").Value + "\"] | "; xpath += ".//xsd:unique[@name=\"" + keyref.Attributes.GetNamedItem("refer").Value + "\"]"; XmlNode key = CurrentSchemaDom.SelectSingleNode(xpath, Namespaces); if (key == null) { throw new ArgumentException("A referenced key couldn't be found."); } foreach (XmlNode node in key.ChildNodes) { if (node.LocalName == "field") { fieldskey.Add( Regex.Replace(node.Attributes.GetNamedItem("xpath").Value, "([A-z|0-9]+):", ""). Replace(".", "").Replace("/", "")); } else if (node.LocalName == "selector") { parentname = Regex.Replace(node.Attributes.GetNamedItem("xpath").Value, "([A-z|0-9]+):", ""). Replace(".", "").Replace("/", ""); } } #region Create Foreign Key CodeExpression[] fields = new CodeExpression[fieldskey.Count]; for (int i = 0; i < fieldskey.Count; i++) { fields[i] = new CodePropertyReferenceExpression( new CodePropertyReferenceExpression( new CodeThisReferenceExpression(), "table" + parentname), fieldskey[i].ToString() + "Column"); } CodeArrayCreateExpression parentfldcreate = new CodeArrayCreateExpression(typeof(DataColumn), fields); fields = new CodeExpression[fieldsref.Count]; for (int i = 0; i < fieldsref.Count; i++) { fields[i] = new CodePropertyReferenceExpression( new CodePropertyReferenceExpression( new CodeThisReferenceExpression(), "table" + element.Name), fieldsref[i].ToString() + "Column"); } CodeArrayCreateExpression childfldcreate = new CodeArrayCreateExpression(typeof(DataColumn), fields); //fkc = new ForeignKeyConstraint("publisherstitles", new DataColumn[] { // this.tablepublishers.pub_idColumn, // this.tablepublishers.pub_nameColumn}, new DataColumn[] { // this.tabletitles.titlepub_idColumn, // this.tabletitles.titleColumn}); initclass.Statements.Add( new CodeAssignStatement( new CodeVariableReferenceExpression("fkc"), new CodeObjectCreateExpression(typeof(ForeignKeyConstraint), new CodeExpression[] { new CodePrimitiveExpression(fkname), parentfldcreate, childfldcreate }))); #endregion #region Add and initialize the Foreign Key //this.tabletitles.Constraints.Add(fkc); initclass.Statements.Add( new CodeMethodInvokeExpression( new CodePropertyReferenceExpression( new CodePropertyReferenceExpression( new CodeThisReferenceExpression(), "table" + element.Name), "Constraints"), "Add", new CodeExpression[] { new CodeVariableReferenceExpression("fkc") })); //fkc.AcceptRejectRule = AcceptRejectRule.None; CodeExpression arrule = new CodeFieldReferenceExpression( new CodeTypeReferenceExpression(typeof(AcceptRejectRule)), "None"); if (keyref.Attributes.GetNamedItem("AcceptRejectRule") != null) { arrule = new CodeFieldReferenceExpression( new CodeTypeReferenceExpression(typeof(AcceptRejectRule)), keyref.Attributes.GetNamedItem("AcceptRejectRule").Value); } initclass.Statements.Add( new CodeAssignStatement( new CodePropertyReferenceExpression( new CodeVariableReferenceExpression("fkc"), "AcceptRejectRule"), arrule)); //fkc.DeleteRule = Rule.Cascade; CodeExpression rule = new CodeFieldReferenceExpression( new CodeTypeReferenceExpression(typeof(Rule)), "Cascade"); if (keyref.Attributes.GetNamedItem("DeleteRule") != null) { arrule = new CodeFieldReferenceExpression( new CodeTypeReferenceExpression(typeof(Rule)), keyref.Attributes.GetNamedItem("DeleteRule").Value); } initclass.Statements.Add( new CodeAssignStatement( new CodePropertyReferenceExpression( new CodeVariableReferenceExpression("fkc"), "DeleteRule"), rule)); //fkc.UpdateRule = Rule.Cascade; rule = new CodeFieldReferenceExpression( new CodeTypeReferenceExpression(typeof(Rule)), "Cascade"); if (keyref.Attributes.GetNamedItem("UpdateRule") != null) { arrule = new CodeFieldReferenceExpression( new CodeTypeReferenceExpression(typeof(Rule)), keyref.Attributes.GetNamedItem("UpdateRule").Value); } initclass.Statements.Add( new CodeAssignStatement( new CodePropertyReferenceExpression( new CodeVariableReferenceExpression("fkc"), "UpdateRule"), rule)); #endregion #region Add and initialize the DataRelation if (keyref.Attributes.GetNamedItem("ConstraintOnly") == null || keyref.Attributes.GetNamedItem("ConstraintOnly").Value != "false") { string relation = keyref.Attributes.GetNamedItem("name").Value; //private DataRelation relationpublisherstitles; (at dataset-level) CodeMemberField fld = new CodeMemberField( typeof(DataRelation), "relation" + keyref.Attributes.GetNamedItem("name").Value); fld.Attributes = MemberAttributes.Private; CurrentDataSetType.Members.Add(fld); //In InitVars: //this.relationpublisherstitles = this.Relations["publisherstitles"]; initvars.Statements.Add( new CodeAssignStatement( new CodePropertyReferenceExpression( new CodeThisReferenceExpression(), "relation" + relation), new CodeIndexerExpression( new CodePropertyReferenceExpression( new CodeThisReferenceExpression(), "Relations"), new CodeExpression[] { new CodePrimitiveExpression(relation) }))); //this.relationpublisherstitles = new DataRelation("publisherstitles", new DataColumn[] { // this.tablepublishers.pub_idColumn, // this.tablepublishers.pub_nameColumn}, new DataColumn[] { // this.tabletitles.titlepub_idColumn, // this.tabletitles.titleColumn}, false); initclass.Statements.Add( new CodeAssignStatement( new CodePropertyReferenceExpression( new CodeThisReferenceExpression(), "relation" + relation), new CodeObjectCreateExpression( typeof(DataRelation), new CodeExpression[] { new CodePrimitiveExpression(relation), parentfldcreate, childfldcreate }))); //this.relationpublishertitles.Nested = true; if (element.Parent != null && element.Parent is VisitableElementComplexType) { initclass.Statements.Add( new CodeAssignStatement( new CodePropertyReferenceExpression( new CodePropertyReferenceExpression( new CodeThisReferenceExpression(), "relation" + relation), "Nested"), new CodePrimitiveExpression(true))); } //this.Relations.Add(this.relationpublisherstitles); initclass.Statements.Add( new CodeMethodInvokeExpression( new CodePropertyReferenceExpression( new CodeThisReferenceExpression(), "Relations"), "Add", new CodeExpression[] { new CodePropertyReferenceExpression( new CodeThisReferenceExpression(), "relation" + relation) })); // Add the property to retrieve child rows to the parent type. parentname += Configuration.TypeNaming; string childname = element.Name + Configuration.TypeNaming; foreach (CodeTypeMember type in CurrentNamespace.Types) { if (type.Name == parentname) { //public titlesRow[] GettitlesRows() { // return ((titlesRow[]) // (this.GetChildRows(this.Table.ChildRelations["publisherstitles"]))); } CodeMemberMethod getrows = new CodeMemberMethod(); getrows.Attributes = MemberAttributes.Public | MemberAttributes.Final; getrows.ReturnType = new CodeTypeReference(childname, 0); getrows.Name = "Get" + childname; getrows.Statements.Add( new CodeMethodReturnStatement( new CodeCastExpression(new CodeTypeReference(childname, 0), new CodeMethodInvokeExpression( new CodeThisReferenceExpression(), "GetChildRows", new CodeExpression[] { new CodeIndexerExpression( new CodePropertyReferenceExpression( new CodePropertyReferenceExpression( new CodeThisReferenceExpression(), "Table"), "ChildRelations"), new CodeExpression[] { new CodePrimitiveExpression(relation) }) })))); break; } } } #endregion } #endregion /* * internal void InitVars() { * this.relationtitlestitleauthors = this.Relations["titlestitleauthors"]; * } */ #region Add the Get* method to the parent elements in the relations /* * public titlesRow[] GettitlesRows() * { * return ((titlesRow[])(this.GetChildRows(this.Table.ChildRelations["publisherstitles"]))); * } */ #endregion } }
/// <summary> /// Looks for keys which use the element, and adds parent or child references. /// </summary> /// <param name="element">The element being inspected.</param> /// <remarks>In an xsd schema, the following represents a foreign-key: /// >xsd:keyref name="publisherstitles" refer="publisherKey"< /// >xsd:selector xpath=".//mstns:titles" /< /// >xsd:field xpath="mstns:pub_id" /< /// >/xsd:keyref< /// the "refer" attribute designates the parent key. /// The xsd:selector represents the child element and xsd:field the /// children field which points to the parent key. There may be multiple fields. /// </remarks> public override void Visit(VisitableElementComplexType element) { base.Visit(element); if (!IsDataSet) { string xpath; #region Look for parent relations // We need to look for every keyref where the current element appears in the xsd:selector element xpath = ".//"; xpath += RetrievePrefix(); xpath += element.Name; xpath = ".//xsd:keyref[xsd:selector/@xpath=\"" + xpath + "\"]"; XmlNodeList keyrefs = CurrentSchemaDom.SelectNodes(xpath, Namespaces); foreach (XmlNode keyref in keyrefs) { string parent; xpath = ".//xsd:key[@name=\"" + keyref.Attributes["refer"].Value + "\"] | "; xpath += ".//xsd:unique[@name=\"" + keyref.Attributes["refer"].Value + "\"]"; XmlNode key = CurrentSchemaDom.SelectSingleNode(xpath, Namespaces); XmlNode parentnode = CurrentSchemaDom.SelectSingleNode( "//xsd:element[@name=\"" + Regex.Replace(key.SelectSingleNode("xsd:selector/@xpath", Namespaces).Value, "([A-z|0-9|.|/]+):", "") + "\"]", Namespaces); parent = parentnode.Attributes["name"].Value; //public publishersRow publishers CodeMemberProperty prop = new CodeMemberProperty(); prop.Name = parent; prop.Attributes = MemberAttributes.Public; prop.HasGet = true; prop.HasSet = true; prop.Type = new CodeTypeReference(parent + Configuration.TypeNaming); #region Property Get // get { // return ((publishersRow)GetParentRow("publisherstitles", typeof(publishersRow))); // } prop.GetStatements.Add( //return new CodeMethodReturnStatement( //(publishersRow) new CodeCastExpression( parent + Configuration.TypeNaming, //(GetParentRow new CodeMethodInvokeExpression(null, "GetParentRow", //"publishertitltes" new CodeExpression[] { new CodePrimitiveExpression(keyref.Attributes["name"].Value), //, typeof(publishersRow) new CodeTypeOfExpression(parent + Configuration.TypeNaming) })))); #endregion #region Property Set // set { SetParentRow(value, this.Table.ParentRelations["publisherstitles"]); } prop.SetStatements.Add( //SetParentRow new CodeMethodInvokeExpression(null, "SetParentRow", new CodeExpression[] { //(value new CodeVariableReferenceExpression("value"), //, this.Table.ParentRelations new CodeIndexerExpression( new CodePropertyReferenceExpression( new CodePropertyReferenceExpression( new CodeThisReferenceExpression(), "Table"), "ParentRelations"), //["publisherstitles"] new CodePrimitiveExpression(keyref.Attributes["name"].Value)) })); #endregion CurrentType.Members.Add(prop); } #endregion #region Look for child relations // We need to look for every keyref where the current element appears in the "refer" key xpath = ".//"; xpath += RetrievePrefix(); xpath += element.Name; xpath = ".//xsd:key[xsd:selector/@xpath=\"" + xpath + "\"] | " + ".//xsd:unique[xsd:selector/@xpath=\"" + xpath + "\"]"; XmlNodeList keys = CurrentSchemaDom.SelectNodes(xpath, Namespaces); // For each key, try to find a keyref pointing to it. foreach (XmlNode key in keys) { xpath = ".//xsd:keyref[@refer=\"" + key.Attributes["name"].Value + "\"]"; XmlNode keyref = CurrentSchemaDom.SelectSingleNode(xpath, Namespaces); if (keyref != null) { // Convert ".//mstns:titles" to "titles" string child = Regex.Replace( keyref.SelectSingleNode("xsd:selector/@xpath", Namespaces).Value, "([A-z|0-9|.|/]+):", ""); //public titlesRow[] titles() { // return ((titlesRow[])(GetChildRows("publisherstitles", typeof(titlesRow))); //} CodeMemberProperty prop = new CodeMemberProperty(); //titlesRow[] CodeTypeReference type = new CodeTypeReference(child + Configuration.TypeNaming, 1); prop.Name = child; prop.Type = type; prop.Attributes = MemberAttributes.Public | MemberAttributes.Final; prop.HasGet = true; prop.GetStatements.Add( //return new CodeMethodReturnStatement( //(titlesRow[]) new CodeCastExpression(type, new CodeMethodInvokeExpression(null, "GetChildRows", new CodeExpression[] { //"publisherstitles" new CodePrimitiveExpression(keyref.Attributes["name"].Value), new CodeTypeOfExpression(child + Configuration.TypeNaming) })))); CurrentType.Members.Add(prop); } } #endregion } }