/// <summary> /// Generates a property to get a parent row. /// </summary> /// <param name="keyrefSchema">The foreign key that references the parent table.</param> public TableParentRelationField(KeyrefSchema keyrefSchema) { // // The Relation between the Department and Employee tables // private Relation relationDepartmentEmployee; this.Type = new CodeTypeReference("Relation"); this.Name = string.Format("relation{0}{1}", keyrefSchema.Refer.Selector.Name, keyrefSchema.Selector.Name); this.Comments.Add(new CodeCommentStatement(string.Format("The Relation between the {0} and {1} tables", keyrefSchema.Refer.Selector.Name, keyrefSchema.Selector.Name))); }
/// <summary> /// Generates a property to get a parent row. /// </summary> /// <param name="keyrefSchema">The foreign key that references the parent table.</param> public TableChildRelationField(KeyrefSchema keyrefSchema) { // // The Relation between the Employee and ProjectMember tables // private Relation relationEmployeeProjectMember; this.Type = new CodeTypeReference("Relation"); this.Name = string.Format("relation{0}{1}", keyrefSchema.Refer.Selector.Name, keyrefSchema.Selector.Name); this.Comments.Add(new CodeCommentStatement(string.Format("The Relation between the {0} and {1} tables", keyrefSchema.Refer.Selector.Name, keyrefSchema.Selector.Name))); }
public override bool Equals(object obj) { if (obj is KeyrefSchema) { KeyrefSchema keyrefSchema = obj as KeyrefSchema; return(this.QualifiedName.Equals(keyrefSchema.QualifiedName)); } return(false); }
/// <summary> /// Gets the parent keys of just the table requested. /// </summary> /// <param name="foreignKeyList"></param> /// <param name="elementTable"></param> private void GetMemberParentKeys(List <KeyrefSchema> foreignKeyList) { foreach (ConstraintSchema constraintSchema in this.Constraints) { if (constraintSchema is KeyrefSchema) { KeyrefSchema keyrefSchema = constraintSchema as KeyrefSchema; foreignKeyList.Add(keyrefSchema); } } }
/// <summary> /// The constraints must be initialized after the tables are constructed. /// </summary> /// <param name="xmlSchema"></param> private void InitializeConstraints(XmlSchema xmlSchema) { // This will scan each of the top-level element of the schema looking for Unique and Key constraints. These // constraints must be defined before the KeyRef constraints are created because the KeyRef constraints reference the // Unique and Key constraints. foreach (XmlSchemaObject xmlSchemaObject in xmlSchema.Items) { if (xmlSchemaObject is XmlSchemaElement) { XmlSchemaElement xmlSchemaElement = xmlSchemaObject as XmlSchemaElement; foreach (XmlSchemaIdentityConstraint xmlSchemaIdentityConstraint in xmlSchemaElement.Constraints) { if (xmlSchemaIdentityConstraint is XmlSchemaUnique) { UniqueSchema uniqueSchema = new UniqueSchema(this, xmlSchemaIdentityConstraint as XmlSchemaUnique); uniqueSchema.Selector.Constraints.Add(uniqueSchema); } if (xmlSchemaIdentityConstraint is XmlSchemaKey) { KeySchema keySchema = new KeySchema(this, xmlSchemaIdentityConstraint as XmlSchemaKey); keySchema.Selector.Constraints.Add(keySchema); } } } } // Once the Key and Unique constraints are described, the schema can be scanned for Keyref schemas. The 'Refer' // property of the KeyrefSchema objects points to the KeySchema or UniqueSchema. foreach (XmlSchemaObject xmlSchemaObject in xmlSchema.Items) { if (xmlSchemaObject is XmlSchemaElement) { XmlSchemaElement xmlSchemaElement = xmlSchemaObject as XmlSchemaElement; foreach (XmlSchemaIdentityConstraint xmlSchemaIdentityConstraint in xmlSchemaElement.Constraints) { if (xmlSchemaIdentityConstraint is XmlSchemaKeyref) { KeyrefSchema keyrefSchema = new KeyrefSchema(this, xmlSchemaIdentityConstraint as XmlSchemaKeyref); keyrefSchema.Selector.Constraints.Add(keyrefSchema); } } } } }
/// <summary> /// Generates a property to get a parent row. /// </summary> /// <param name="keyrefSchema">The foreign key that references the parent table.</param> public TableParentRelationProperty(KeyrefSchema keyrefSchema) { // /// <summary> // /// Gets the parent relation between the Department and Employee tables. // /// </summary> // internal Relation DepartmentEmployeeRelation // { // get // { // return this.relationDepartmentEmployee; // } // } this.Comments.Add(new CodeCommentStatement("<summary>", true)); this.Comments.Add(new CodeCommentStatement(string.Format("Gets the parent relation between the {0} and {1} tables.", keyrefSchema.Refer.Selector.Name, keyrefSchema.Selector.Name), true)); this.Comments.Add(new CodeCommentStatement("</summary>", true)); this.Attributes = MemberAttributes.Assembly | MemberAttributes.Final; this.Type = new CodeTypeReference("Relation"); this.Name = string.Format("{0}{1}Relation", keyrefSchema.Refer.Selector.Name, keyrefSchema.Selector.Name); this.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), string.Format("relation{0}{1}", keyrefSchema.Refer.Selector.Name, keyrefSchema.Selector.Name)))); }
/// <summary> /// Generates the foreign keys on a table. /// </summary> /// <param name="streamWriter">The file to which the DDL is written.</param> /// <param name="tableSchema">The schema description of the table.</param> private static void GenerateForeignKeys(StreamWriter streamWriter, TableSchema tableSchema) { // This will generate the foreign keys for the table. if (tableSchema.ParentKeyrefs.Count != 0) { streamWriter.WriteLine(" /* Foreign Keys */"); streamWriter.WriteLine(" alter table \"{0}\" add ", tableSchema.Name); for (int foreignKeyIndex = 0; foreignKeyIndex < tableSchema.ParentKeyrefs.Count; foreignKeyIndex++) { KeyrefSchema keyrefSchema = tableSchema.ParentKeyrefs[foreignKeyIndex] as KeyrefSchema; streamWriter.WriteLine(" constraint \"{0}\" foreign key ", keyrefSchema.Name); streamWriter.WriteLine(" ("); // Generate the child field names. ColumnSchema[] childFields = keyrefSchema.Fields; for (int columnIndex = 0; columnIndex < childFields.Length; columnIndex++) { ColumnSchema columnSchema = childFields[columnIndex]; streamWriter.Write(" \"{0}\"", columnSchema.Name); streamWriter.WriteLine(columnIndex == childFields.Length - 1 ? "" : ","); } // Generate the parent 'refer' selector and field names. streamWriter.WriteLine(" ) references \"{0}\" (", keyrefSchema.Refer.Selector.Name); ColumnSchema[] parentFields = keyrefSchema.Refer.Fields; for (int columnIndex = 0; columnIndex < childFields.Length; columnIndex++) { ColumnSchema columnSchema = parentFields[columnIndex]; streamWriter.Write(" \"{0}\"", columnSchema.Name); streamWriter.WriteLine(columnIndex == childFields.Length - 1 ? "" : ","); } // End with a comment if there are more foreign constraints comming. streamWriter.WriteLine(foreignKeyIndex < tableSchema.ParentKeyrefs.Count - 1 ? " ),": " )"); } // Roll the transaction back on errors. streamWriter.WriteLine(""); } }
private void ConstraintAddedHandler(object sender, ConstraintEventArgs constraintEventArgs) { if (constraintEventArgs.ConstraintSchema.IsPrimaryKey) { this.primaryKey = constraintEventArgs.ConstraintSchema; } if (constraintEventArgs.ConstraintSchema is KeySchema) { this.Keys.Add(constraintEventArgs.ConstraintSchema as KeySchema); } if (constraintEventArgs.ConstraintSchema is UniqueSchema) { this.Keys.Add(constraintEventArgs.ConstraintSchema as UniqueSchema); } if (constraintEventArgs.ConstraintSchema is KeyrefSchema) { KeyrefSchema keyrefSchema = constraintEventArgs.ConstraintSchema as KeyrefSchema; bool isMatch = keyrefSchema.Fields.Length == primaryKey.Fields.Length; for (int index = 0; index < keyrefSchema.Fields.Length; index++) { if (keyrefSchema.Fields[index] != primaryKey.Fields[index]) { isMatch = false; break; } } if (isMatch) { this.baseTable = keyrefSchema.Refer.Selector; } this.ParentKeyrefs.Add(keyrefSchema); } }
/// <summary> /// Indicates that a column is an identity column. /// </summary> /// <param name="columnSchema">The description of a column.</param> /// <returns>true if the column has an internally generated identifier.</returns> public bool IsIdentityColumn(ColumnSchema columnSchema) { if (columnSchema.IsAutoIncrement) { return(true); } // See if the column may is part of an identity column in the base table. TableSchema baseTable = this.BaseTable; if (baseTable != null) { // See if the column is the identity column in the base table. if (baseTable.IsIdentityColumn(columnSchema)) { return(true); } // If the column is part of the primary key, then it's possible that the column is an identity column through a // primary key relation. ConstraintSchema keySchema = this.PrimaryKey; if (keySchema != null && keySchema.Fields.Length == 1 && keySchema.Fields[0] == columnSchema) { // See if the column is related to an identity column through the primary index. ConstraintSchema baseKeySchema = baseTable.PrimaryKey; KeyrefSchema baseKeyRefSchema = this.FindForeignKey(new ColumnSchema[] { columnSchema }); if (baseKeyRefSchema != null && baseKeyRefSchema.Refer == baseKeySchema) { if (baseKeySchema.Fields.Length == 1) { ColumnSchema baseColumnSchema = baseTable.Columns[baseKeySchema.Fields[0].QualifiedName]; return(baseTable.IsExternalIdColumn(baseColumnSchema)); } } } } return(false); }
/// <summary> /// Finds a foreign key that matches the table and collection of columns. /// </summary> /// <param name="elementTable">An element describing the table to be searched.</param> /// <param name="columnSchema">A collection of elements describing the columns in the foreign key.</param> /// <returns>A foreign key, or null if there is no match to the table/column combination.</returns> public KeyrefSchema FindForeignKey(ColumnSchema[] columns) { foreach (ConstraintSchema constraintSchema in this.Constraints) { if (constraintSchema is KeyrefSchema) { // Create a Strongly Typed Keyref record. KeyrefSchema keyrefSchema = constraintSchema as KeyrefSchema; // A match must include all of the columns in the foreign key. Try every permuatation of field against // field looking for a match. if (keyrefSchema.Selector == this) { int matches = 0; foreach (ColumnSchema fieldSchema in keyrefSchema.Fields) { foreach (ColumnSchema columnSchema in columns) { if (fieldSchema == columnSchema) { matches++; } } } // If the number of matches found is the same as the number of columns in the key, then this record is a match. if (matches == columns.Length) { return(keyrefSchema); } } } } // At this point, no matching keys were found. TableSchema baseTable = this.BaseTable; return(baseTable == null ? null : baseTable.FindForeignKey(columns)); }
private void GetParentKeys(List <KeyrefSchema> parentKeys) { // Recurse down into the base classes looking for parent keys. TableSchema baseTable = this.BaseTable; if (baseTable != null) { baseTable.GetParentKeys(parentKeys); } // Search through all the foreign keys looking for a selector that matches the given table name. foreach (ConstraintSchema constraintSchema in this.Constraints) { if (constraintSchema is KeyrefSchema) { KeyrefSchema keyrefSchema = constraintSchema as KeyrefSchema; if (keyrefSchema.Selector == this) { parentKeys.Add(keyrefSchema); } } } }
/// <summary> /// Generates a property to get a parent row. /// </summary> /// <param name="keyrefSchema">The foreign key that references the parent table.</param> public RowParentRowProperty(KeyrefSchema keyrefSchema) { // These constructs are used several times to generate the property. TableSchema childTable = keyrefSchema.Selector; TableSchema parentTable = keyrefSchema.Refer.Selector; string rowTypeName = string.Format("{0}Row", parentTable.Name); string tableFieldName = string.Format("table{0}", childTable.Name); string relationName = string.Format("{0}{1}Relation", parentTable.Name, childTable.Name); // To reduce the frequency of deadlocking, the tables are always locked in alphabetical order. This section collects // all the table locks that are used for this operation and organizes them in a list that is used to generate the // locking and releasing statements below. List <LockRequest> tableLockList = new List <LockRequest>(); tableLockList.Add(new ReadRequest(childTable)); tableLockList.Add(new ReadRequest(parentTable)); tableLockList.Sort(); // If the foreign keys share the same primary key, then the names of the methods will need to be decorated with the // key name in order to make them unique. This will test the foreign keys for duplicate primary key names. bool isDuplicateKey = false; foreach (KeyrefSchema otherKeyrefSchema in childTable.MemberParentKeys) { if (otherKeyrefSchema != keyrefSchema && otherKeyrefSchema.Refer.Name == keyrefSchema.Refer.Name) { isDuplicateKey = true; } } // /// <summary> // /// Gets the parent row in the Race table. // /// </summary> // public RaceRow RaceRow // { this.Comments.Add(new CodeCommentStatement("<summary>", true)); this.Comments.Add(new CodeCommentStatement(string.Format("Gets the parent row in the {0} table.", keyrefSchema.Refer.Selector.Name), true)); this.Comments.Add(new CodeCommentStatement("</summary>", true)); this.Attributes = MemberAttributes.Public | MemberAttributes.Final; this.Type = new CodeTypeReference(rowTypeName); this.Name = isDuplicateKey ? string.Format("{0}By{1}", rowTypeName, keyrefSchema.Name) : rowTypeName; // if (this.ReaderWriterLock.IsReaderLockHeld == false && this.ReaderWriterLock.IsWriterLockHeld == false) // throw new LockException("An attempt was made to access an Employee Row without a lock"); this.GetStatements.Add(new CodeCommentStatement("This insures the row is locked before attempting to access the parent row.")); this.GetStatements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodeBinaryOperatorExpression(new CodeFieldReferenceExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "ReaderWriterLock"), "IsReaderLockHeld"), CodeBinaryOperatorType.IdentityEquality, new CodePrimitiveExpression(false)), CodeBinaryOperatorType.BooleanAnd, new CodeBinaryOperatorExpression(new CodeFieldReferenceExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "ReaderWriterLock"), "IsWriterLockHeld"), CodeBinaryOperatorType.IdentityEquality, new CodePrimitiveExpression(false))), new CodeThrowExceptionStatement(new CodeObjectCreateExpression(new CodeTypeReference("MarkThree.LockException"), new CodePrimitiveExpression(string.Format("Attempt was made to access a row in {0} without a lock.", childTable.Name)))))); // get // { CodeTryCatchFinallyStatement getTryStatement = new CodeTryCatchFinallyStatement(); // try // { // // The parent table must be locked before attempting to access the parent row. // this.tableEmployee.RaceEmployeeRelation.ParentTable.ReaderWriterLock.AcquireReaderLock(System.Threading.Timeout.Infinite); // return ((RaceRow)(this.GetParentRow(this.tableEmployee.RaceEmployeeRelation))); // } // finally // { // // The parent table can be released once the parent row is found. // this.tableEmployee.RaceEmployeeRelation.ParentTable.ReaderWriterLock.ReleaseReaderLock(); // } getTryStatement.TryStatements.Add(new CodeCommentStatement("The parent table must be locked to insure it doesn't change before attempting to access the parent row.")); CodeExpression parentRelationExpression = new CodeFieldReferenceExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), tableFieldName), relationName); foreach (LockRequest lockRequest in tableLockList) { getTryStatement.TryStatements.Add(new CodeMethodInvokeExpression(new CodeFieldReferenceExpression(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(keyrefSchema.Selector.DataModelSchema.Name), lockRequest.TableSchema.Name), "ReaderWriterLock"), "AcquireReaderLock", new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(System.Threading.Timeout)), "Infinite"))); } getTryStatement.TryStatements.Add(new CodeMethodReturnStatement(new CodeCastExpression(rowTypeName, new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "GetParentRow", new CodeFieldReferenceExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), tableFieldName), string.Format("{0}{1}Relation", keyrefSchema.Refer.Selector.Name, keyrefSchema.Selector.Name)))))); getTryStatement.FinallyStatements.Add(new CodeCommentStatement("The parent table can be released once the parent row is found.")); foreach (LockRequest lockRequest in tableLockList) { getTryStatement.FinallyStatements.Add(new CodeMethodInvokeExpression(new CodeFieldReferenceExpression(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(keyrefSchema.Selector.DataModelSchema.Name), lockRequest.TableSchema.Name), "ReaderWriterLock"), "ReleaseReaderLock")); } // } this.GetStatements.Add(getTryStatement); // } }
/// <summary> /// Creates a method to delete a record in the ADO database. /// </summary> /// <param name="coreInterfaceClass"></param> /// <param name="this.TableSchema.ElementTable"></param> private void ArchiveWithBase() { // Shorthand notations for the elements used to construct the interface to this table: string tableTypeName = string.Format("{0}.{1}DataTable", this.ServerSchema.Name, this.TableSchema.Name); string tableVariableName = string.Format("{0}Table", this.TableSchema.Name[0].ToString().ToLower() + this.TableSchema.Name.Remove(0, 1)); string rowTypeName = string.Format("{0}.{1}Row", this.ServerSchema.Name, this.TableSchema.Name); string rowVariableName = string.Format("{0}Row", this.TableSchema.Name[0].ToString().ToLower() + this.TableSchema.Name.Remove(0, 1)); string identityColumnName = this.TableSchema.PrimaryKey.Fields[0].Name; string identityVariableName = identityColumnName[0].ToString().ToLower() + identityColumnName.Remove(0, 1); // Method Header: // /// <summary>Archives a Algorithm record.</summary> // /// <param name="transaction">Commits or rejects a set of commands as a unit</param> // /// <param name="algorithmId">The value for the AlgorithmId column.</param> // /// <param name="rowVersion">The value for the RowVersion column.</param> // public static void Archive(Transaction transaction, int algorithmId, long rowVersion) // { this.Comments.Add(new CodeCommentStatement(string.Format("<summary>Archives a {0} record.</summary>", this.TableSchema.Name), true)); this.Comments.Add(new CodeCommentStatement(@"<param name=""transaction"">Commits or rejects a set of commands as a unit</param>", true)); this.Comments.Add(new CodeCommentStatement(@"<param name=""rowVersion"">The version number of this row.</param>", true)); foreach (ColumnSchema columnSchema in this.TableSchema.Columns) { if (columnSchema.DeclaringType == this.TableSchema.TypeSchema && this.TableSchema.IsPrimaryKeyColumn(columnSchema)) { string variableName = columnSchema.Name[0].ToString().ToLower() + columnSchema.Name.Remove(0, 1); this.Comments.Add(new CodeCommentStatement(string.Format(@"<param name=""{0}"">The value for the {1} column.</param>", variableName, columnSchema.Name), true)); } } this.Comments.Add(new CodeCommentStatement(@"<param name=""archive"">true to archive the object, false to unarchive it.</param>", true)); this.Attributes = MemberAttributes.Public | MemberAttributes.Final | MemberAttributes.Static | MemberAttributes.New; this.Name = "Archive"; this.Parameters.Add(new CodeParameterDeclarationExpression("AdoTransaction", "adoTransaction")); this.Parameters.Add(new CodeParameterDeclarationExpression("SqlTransaction", "sqlTransaction")); this.Parameters.Add(new CodeParameterDeclarationExpression(typeof(long), "rowVersion")); foreach (ColumnSchema columnSchema in this.TableSchema.Columns) { if (columnSchema.DeclaringType == this.TableSchema.TypeSchema && this.TableSchema.IsPrimaryKeyColumn(columnSchema)) { string variableName = columnSchema.Name[0].ToString().ToLower() + columnSchema.Name.Remove(0, 1); this.Parameters.Add(new CodeParameterDeclarationExpression(columnSchema.DataType, variableName)); } } // Get an accessor to the table schema information. This makes accessing information about the table much faster as // it doesn't need to do the lock checking each time it references the table. // // Accessor for the Algorithm Table. // ServerMarketData.AlgorithmDataTable algorithmTable = ServerMarketData.Algorithm; this.Statements.Add(new CodeCommentStatement(string.Format("Accessor for the {0} Table.", this.TableSchema.Name))); this.Statements.Add(new CodeVariableDeclarationStatement(new CodeTypeReference(tableTypeName), tableVariableName, new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(this.ServerSchema.Name), this.TableSchema.Name))); // Rule #1: Make sure the record exists. // // Rule #1: Make sure the record exists before updating it. // ServerMarketData.AlgorithmRow algorithmRow = algorithmTable.FindByAlgorithmId(algorithmId); // if ((algorithmRow == null)) // { // throw new Exception(string.Format("The Algorithm table does not have an element identified by {0}", algorithmId)); // } this.Statements.Add(new CodeCommentStatement(string.Format("Rule #1: Make sure the record exists before updating it.", this.TableSchema.Name))); string keyColumns = string.Empty; string exeptionFormat = string.Empty; CodeExpression[] keyVariables = new CodeExpression[this.TableSchema.PrimaryKey.Fields.Length]; CodeExpression[] exceptionVariables = new CodeExpression[this.TableSchema.PrimaryKey.Fields.Length + 1]; for (int index = 0; index < this.TableSchema.PrimaryKey.Fields.Length; index++) { string columnName = this.TableSchema.PrimaryKey.Fields[index].Name; string variableName = columnName[0].ToString().ToLower() + columnName.Remove(0, 1); keyColumns += columnName; exeptionFormat += string.Format("{{0}}", index); keyVariables[index] = new CodeVariableReferenceExpression(variableName); exceptionVariables[index + 1] = new CodeVariableReferenceExpression(variableName); } exceptionVariables[0] = new CodePrimitiveExpression(string.Format("The {0} table does not have an element identified by {1}", this.TableSchema.Name, exeptionFormat)); this.Statements.Add(new CodeVariableDeclarationStatement(rowTypeName, rowVariableName, new CodeMethodInvokeExpression(new CodeArgumentReferenceExpression(tableVariableName), string.Format("FindBy{0}", keyColumns), keyVariables))); this.Statements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression(rowVariableName), CodeBinaryOperatorType.IdentityEquality, new CodePrimitiveExpression(null)), new CodeThrowExceptionStatement(new CodeObjectCreateExpression("Exception", new CodeExpression[] { new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(string)), "Format", exceptionVariables) })))); // Rule #2: Optimistic Concurrency Check. // // Rule #2: Optimistic Concurrency Check // if ((algorithmRow.RowVersion != rowVersion)) // { // throw new System.Exception("This record is busy. Please try again later."); // } this.Statements.Add(new CodeCommentStatement("Rule #2: Optimistic Concurrency Check")); CodeStatement[] trueTest2Array = new CodeStatement[] { new CodeThrowExceptionStatement(new CodeObjectCreateExpression(typeof(System.Exception), new CodeExpression[] { new CodePrimitiveExpression("This record is busy. Please try again later.") })) }; this.Statements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodeFieldReferenceExpression(new CodeVariableReferenceExpression(rowVariableName), "RowVersion"), CodeBinaryOperatorType.IdentityInequality, new CodeVariableReferenceExpression("rowVersion")), trueTest2Array)); // This mess determines what the name of the parent row accessor is. The complication occurs when there are more than // one foreign keys back to the parent table. In this case, the code generator decorates the name of the row accessor // with the Foreign key name. bool hasMultipleParentKeys = false; KeyrefSchema baseKeyref = null; foreach (KeyrefSchema outerKeyref in this.TableSchema.ParentKeyrefs) { if (outerKeyref.Selector == this.TableSchema.BaseTable) { baseKeyref = outerKeyref; } foreach (KeyrefSchema innerKeyref in this.TableSchema.ParentKeyrefs) { if (outerKeyref != innerKeyref && outerKeyref.Selector == innerKeyref.Selector) { hasMultipleParentKeys = true; } } } string parentRowAccessor = hasMultipleParentKeys ? string.Format("{0}RowBy{1}", this.TableSchema.BaseTable.Name, baseKeyref.Name) : string.Format("{0}Row", this.TableSchema.BaseTable.Name); // Call the base class to delete the base object this.Statements.Add(new CodeCommentStatement("Delete the base class record. Note that optimistic concurrency is only used")); this.Statements.Add(new CodeCommentStatement("by the top level type in the hierarchy, it is bypassed after you pass the first test.")); this.Statements.Add(new CodeVariableDeclarationStatement(typeof(long), "baseRowVersion", new CodeFieldReferenceExpression(new CodeFieldReferenceExpression(new CodeVariableReferenceExpression(rowVariableName), parentRowAccessor), "RowVersion"))); this.Statements.Add(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(this.TableSchema.BaseTable.Name), "Archive", new CodeExpression[] { new CodeArgumentReferenceExpression("adoTransaction"), new CodeArgumentReferenceExpression("sqlTransaction"), new CodeArgumentReferenceExpression("baseRowVersion"), new CodeArgumentReferenceExpression(identityVariableName) })); }
/// <summary> /// Indicates that the given foreign key is a reference to the base table. /// </summary> /// <param name="keyrefSchema">A foreign key description.</param> /// <returns>true if the given foreign key refers to the base table.</returns> public bool IsBaseKeyref(KeyrefSchema keyrefSchema) { // A true indicates that the given foreign key references the immediate base class of this table. return(this.BaseTable != null && this.BaseTable == keyrefSchema.Refer.Selector); }
/// <summary> /// Creates a strongly typed DataSet from a schema description. /// </summary> /// <param name="dataSetNamespace">The CodeDOM namespace that contains this strongly typed DataSet.</param> public TypedDataSetClass(MiddleTierNamespace dataSetNamespace) { // Initialize the object. this.dataSetNamespace = dataSetNamespace; // /// <summary> // /// A thread-safe, multi-tiered DataModel. // /// </summary> // [System.ComponentModel.DesignerCategoryAttribute("code")] // [System.Diagnostics.DebuggerStepThrough()] // [System.ComponentModel.ToolboxItem(true)] // public class DataModel : System.ComponentModel.Component // { this.Comments.Add(new CodeCommentStatement("<summary>", true)); this.Comments.Add(new CodeCommentStatement(string.Format("A thread-safe, multi-tiered {0}.", this.Schema.Name), true)); this.Comments.Add(new CodeCommentStatement("</summary>", true)); this.IsClass = true; this.Name = this.Schema.Name; this.TypeAttributes = TypeAttributes.Public; this.BaseTypes.Add(new CodeTypeReference(typeof(Component))); this.CustomAttributes.Add(new CodeAttributeDeclaration("System.ComponentModel.DesignerCategoryAttribute", new CodeAttributeArgument[] { new CodeAttributeArgument(new CodePrimitiveExpression("code")) })); this.CustomAttributes.Add(new CodeAttributeDeclaration("System.Diagnostics.DebuggerStepThrough")); this.CustomAttributes.Add(new CodeAttributeDeclaration("System.ComponentModel.ToolboxItem", new CodeAttributeArgument[] { new CodeAttributeArgument(new CodePrimitiveExpression(true)) })); // // Counts the number of the DataModel has been referenced. // private static int referenceCount; CodeMemberField referenceCountField = new CodeMemberField(); referenceCountField.Comments.Add(new CodeCommentStatement(string.Format("Counts the number of the {0} has been referenced.", this.Schema.Name))); referenceCountField.Attributes = MemberAttributes.Private | MemberAttributes.Static; referenceCountField.Type = new CodeTypeReference(typeof(System.Int32)); referenceCountField.Name = "referenceCount"; this.Members.Add(referenceCountField); // // Represents the in-memory cache of data for the DataModel. // private static DataSet dataSet; CodeMemberField dataSetField = new CodeMemberField(); dataSetField.Comments.Add(new CodeCommentStatement(string.Format("Represents the in-memory cache of data for the {0}.", this.Schema.Name))); dataSetField.Attributes = MemberAttributes.Private | MemberAttributes.Static; dataSetField.Type = new CodeTypeReference("DataSet"); dataSetField.Name = "dataSet"; this.Members.Add(dataSetField); // // The Department table // private static DepartmentDataTable tableDepartment; foreach (TableSchema tableSchema in this.Schema.Tables) { CodeMemberField codeMemberField = new CodeMemberField(); codeMemberField.Comments.Add(new CodeCommentStatement(string.Format("The {0} table", tableSchema.Name))); codeMemberField.Attributes = MemberAttributes.Private | MemberAttributes.Static; codeMemberField.Type = new CodeTypeReference(String.Format("{0}DataTable", tableSchema.Name)); codeMemberField.Name = string.Format("table{0}", tableSchema.Name); this.Members.Add(codeMemberField); } // // Relates the Department table to the Employee table. // private static Relation relationFK_Department_Employee; foreach (TableSchema tableSchema in this.Schema.Tables) { foreach (ConstraintSchema constraintSchema in tableSchema.Constraints) { if (constraintSchema is KeyrefSchema) { KeyrefSchema keyrefSchema = constraintSchema as KeyrefSchema; CodeMemberField codeMemberField = new CodeMemberField(); codeMemberField.Comments.Add(new CodeCommentStatement(string.Format("Relates the {0} table to the {1} table.", keyrefSchema.Refer.Selector.Name, keyrefSchema.Selector.Name))); codeMemberField.Attributes = MemberAttributes.Private | MemberAttributes.Static; codeMemberField.Type = new CodeTypeReference("Relation"); codeMemberField.Name = string.Format("relation{0}", keyrefSchema.Name); this.Members.Add(codeMemberField); } } } // /// <summary> // /// Static Constructor for the DataModel. // /// </summary> // static DataModel() // { CodeTypeConstructor voidTypeConstructor = new CodeTypeConstructor(); voidTypeConstructor.Comments.Add(new CodeCommentStatement("<summary>", true)); voidTypeConstructor.Comments.Add(new CodeCommentStatement(string.Format("Static Constructor for the {0}.", this.Schema.Name), true)); voidTypeConstructor.Comments.Add(new CodeCommentStatement("</summary>", true)); // // Create the DataModel DataSet // DataModel.dataSet = new DataSet(); // DataModel.dataSet.Name = "DataModel"; // DataModel.dataSet.CaseSensitive = true; // DataModel.dataSet.EnforceConstraints = true; voidTypeConstructor.Statements.Add(new CodeCommentStatement(string.Format("Create the {0} DataSet", this.Schema.Name))); voidTypeConstructor.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(this.Schema.Name), "dataSet"), new CodeObjectCreateExpression("DataSet", new CodeExpression[] { }))); voidTypeConstructor.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(this.Schema.Name), "dataSet"), "DataSetName"), new CodePrimitiveExpression(this.Schema.Name))); voidTypeConstructor.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(this.Schema.Name), "dataSet"), "CaseSensitive"), new CodePrimitiveExpression(true))); voidTypeConstructor.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(this.Schema.Name), "dataSet"), "EnforceConstraints"), new CodePrimitiveExpression(true))); // // Create the Department Table. // DataModel.tableDepartment = new DepartmentDataTable(); // DataModel.Tables.Add(DataModel.tableDepartment); foreach (TableSchema tableSchema in this.Schema.Tables) { voidTypeConstructor.Statements.Add(new CodeCommentStatement(string.Format("Create the {0} Table.", tableSchema.Name))); voidTypeConstructor.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(this.Schema.Name), String.Format("table{0}", tableSchema.Name)), new CodeObjectCreateExpression(string.Format("{0}DataTable", tableSchema.Name), new CodeExpression[] { }))); voidTypeConstructor.Statements.Add(new CodeMethodInvokeExpression(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(this.Schema.Name), "Tables"), "Add", new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(this.Schema.Name), String.Format("table{0}", tableSchema.Name)))); } // // Create and enforce the relation between Department and Employee tables. // DataModel.relationFK_Department_Employee = new Relation("FK_Department_Employee", new Column[] { // DataModel.tableDepartment.DepartmentIdColumn}, new Column[] { // DataModel.tableEmployee.DepartmentIdColumn}, true); // DataModel.Relations.Add(DataModel.relationFK_Department_Employee); foreach (TableSchema tableSchema in this.Schema.Tables) { foreach (ConstraintSchema constraintSchema in tableSchema.Constraints) { if (constraintSchema is KeyrefSchema) { // Extract the parent and child tables from the keys. KeyrefSchema keyrefSchema = constraintSchema as KeyrefSchema; ConstraintSchema referSchema = keyrefSchema.Refer; TableSchema parentTable = referSchema.Selector; TableSchema childTable = keyrefSchema.Selector; // Collect the key fields in the parent table. List <CodeExpression> parentFieldList = new List <CodeExpression>(); foreach (ColumnSchema columnSchema in referSchema.Fields) { string parentColumnName = String.Format("{0}Column", columnSchema.Name); string parentTableName = String.Format("table{0}", parentTable.Name); parentFieldList.Add(new CodePropertyReferenceExpression(new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(this.Schema.Name), parentTableName), parentColumnName)); } // Collect the referenced fields in the child table. List <CodeExpression> childFieldList = new List <CodeExpression>(); foreach (ColumnSchema columnSchema in keyrefSchema.Fields) { string childColumnName = String.Format("{0}Column", columnSchema.Name); string childTableName = String.Format("table{0}", childTable.Name); childFieldList.Add(new CodePropertyReferenceExpression(new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(this.Schema.Name), childTableName), childColumnName)); } // Create the CodeDOM statements to create the relationship between the two tables and the foreign key // constraint that insures the integrity of the relation. voidTypeConstructor.Statements.Add(new CodeCommentStatement(string.Format("Create and enforce the relation between {0} and {1} tables.", parentTable.Name, childTable.Name))); CodeObjectCreateExpression newForeignKey = new CodeObjectCreateExpression("Relation", new CodeExpression[] { new CodePrimitiveExpression(keyrefSchema.Name), new CodeArrayCreateExpression("Column", parentFieldList.ToArray()), new CodeArrayCreateExpression("Column", childFieldList.ToArray()), new CodePrimitiveExpression(true) }); voidTypeConstructor.Statements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(this.Schema.Name), string.Format("relation{0}", keyrefSchema.Name)), newForeignKey)); CodeExpression parameterExpression = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(this.Schema.Name), String.Format("relation{0}", keyrefSchema.Name)); voidTypeConstructor.Statements.Add(new CodeMethodInvokeExpression(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(this.Schema.Name), "Relations"), "Add", new CodeExpression[] { parameterExpression })); } } } foreach (TableSchema tableSchema in this.Schema.Tables) { // // Initialze the relation fields for the Department table. // DataModel.Department.InitializeRelations(); voidTypeConstructor.Statements.Add(new CodeCommentStatement(string.Format("Initialze the relation fields for the {0} table.", tableSchema.Name), true)); voidTypeConstructor.Statements.Add(new CodeMethodInvokeExpression(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(this.Schema.Name), tableSchema.Name), "InitializeRelations")); } // } this.Members.Add(voidTypeConstructor); // /// <summary> // /// Initializer for instances of DataModel not managed as a component. // /// </summary> // public DataModel() // { // // This is used to keep track of the number of references to this shared component. When the count drops to zero, the // // external resources (namely the thread) are destroyed. // DataModel.referenceCount = (DataModel.referenceCount + 1); // } CodeConstructor voidConstructor = new CodeConstructor(); voidConstructor.Attributes = MemberAttributes.Public; voidConstructor.Comments.Add(new CodeCommentStatement("<summary>", true)); voidConstructor.Comments.Add(new CodeCommentStatement(string.Format("Initializer for instances of {0} not managed as a component.", this.Schema.Name), true)); voidConstructor.Comments.Add(new CodeCommentStatement("</summary>", true)); voidConstructor.Statements.Add(new CodeCommentStatement("This is used to keep track of the number of references to this shared component. When the count drops to zero, the")); voidConstructor.Statements.Add(new CodeCommentStatement("external resources (namely the thread) are destroyed.")); voidConstructor.Statements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(this.Schema.Name), "referenceCount"), new CodeBinaryOperatorExpression(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(this.Schema.Name), "referenceCount"), CodeBinaryOperatorType.Add, new CodePrimitiveExpression(1)))); this.Members.Add(voidConstructor); // /// <summary> // /// Initializer for instances of DataModel not managed as a component. // /// </summary> // public DataModel(System.ComponentModel.IContainer iContainer) // { // // Add this component to the list of components managed by its client. // iContainer.Add(this); // // This is used to keep track of the number of references to this shared component. When the count drops to zero, the // // external resources (namely the thread) are destroyed. // DataModel.referenceCount = (DataModel.referenceCount + 1); // } CodeConstructor iComponentConstructor = new CodeConstructor(); iComponentConstructor.Attributes = MemberAttributes.Public; iComponentConstructor.Parameters.Add(new CodeParameterDeclarationExpression(typeof(System.ComponentModel.IContainer), "iContainer")); iComponentConstructor.Comments.Add(new CodeCommentStatement("<summary>", true)); iComponentConstructor.Comments.Add(new CodeCommentStatement(string.Format("Initializer for instances of {0} not managed as a component.", this.Schema.Name), true)); iComponentConstructor.Comments.Add(new CodeCommentStatement("</summary>", true)); iComponentConstructor.Statements.Add(new CodeCommentStatement("Add this component to the list of components managed by its client.")); iComponentConstructor.Statements.Add(new CodeMethodInvokeExpression(new CodeArgumentReferenceExpression("iContainer"), "Add", new CodeThisReferenceExpression())); iComponentConstructor.Statements.Add(new CodeCommentStatement("This is used to keep track of the number of references to this shared component. When the count drops to zero, the")); iComponentConstructor.Statements.Add(new CodeCommentStatement("external resources (namely the thread) are destroyed.")); iComponentConstructor.Statements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(this.Schema.Name), "referenceCount"), new CodeBinaryOperatorExpression(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(this.Schema.Name), "referenceCount"), CodeBinaryOperatorType.Add, new CodePrimitiveExpression(1)))); this.Members.Add(iComponentConstructor); // /// <summary> // /// The number of times the DataModel has been referenced. // /// </summary> // [System.ComponentModel.Browsable(false)] // [System.ComponentModel.DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Content)] // public static int ReferenceCount // { // get // { // return DataModel.referenceCount; // } // } CodeMemberProperty referenceCountProperty = new CodeMemberProperty(); this.Members.Add(referenceCountProperty); referenceCountProperty.Comments.Add(new CodeCommentStatement("<summary>", true)); referenceCountProperty.Comments.Add(new CodeCommentStatement(string.Format("The number of times the {0} has been referenced.", this.Schema.Name), true)); referenceCountProperty.Comments.Add(new CodeCommentStatement("</summary>", true)); referenceCountProperty.CustomAttributes.Add(new CodeAttributeDeclaration("System.ComponentModel.Browsable", new CodeAttributeArgument[] { new CodeAttributeArgument(new CodePrimitiveExpression(false)) })); referenceCountProperty.CustomAttributes.Add(new CodeAttributeDeclaration("System.ComponentModel.DesignerSerializationVisibilityAttribute", new CodeAttributeArgument[] { new CodeAttributeArgument(new CodeTypeReferenceExpression("System.ComponentModel.DesignerSerializationVisibility.Content")) })); referenceCountProperty.Attributes = MemberAttributes.Public | MemberAttributes.Static; referenceCountProperty.Type = new CodeTypeReference(typeof(int)); referenceCountProperty.Name = "ReferenceCount"; referenceCountProperty.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(this.Schema.Name), "referenceCount"))); // /// <summary> // /// Gets or sets a value indicating whether constraint rules are followed when attempting any update operation. // /// </summary> // [System.ComponentModel.Browsable(false)] // [System.ComponentModel.DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Content)] // public static bool EnforceConstraints // { // get // { // return DataModel.dataSet.EnforceConstraints; // } // set // { // DataModel.dataSet.EnforceConstraints = value; // } // } CodeMemberProperty enforceConstraintsProperty = new CodeMemberProperty(); enforceConstraintsProperty.Comments.Add(new CodeCommentStatement("<summary>", true)); enforceConstraintsProperty.Comments.Add(new CodeCommentStatement("Gets or sets a value indicating whether constraint rules are followed when attempting any update operation.", true)); enforceConstraintsProperty.Comments.Add(new CodeCommentStatement("</summary>", true)); enforceConstraintsProperty.CustomAttributes.Add(new CodeAttributeDeclaration("System.ComponentModel.Browsable", new CodeAttributeArgument[] { new CodeAttributeArgument(new CodePrimitiveExpression(false)) })); enforceConstraintsProperty.CustomAttributes.Add(new CodeAttributeDeclaration("System.ComponentModel.DesignerSerializationVisibilityAttribute", new CodeAttributeArgument[] { new CodeAttributeArgument(new CodeTypeReferenceExpression("System.ComponentModel.DesignerSerializationVisibility.Content")) })); enforceConstraintsProperty.Attributes = MemberAttributes.Public | MemberAttributes.Static; enforceConstraintsProperty.Type = new CodeTypeReference(typeof(bool)); enforceConstraintsProperty.Name = "EnforceConstraints"; enforceConstraintsProperty.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(this.Schema.Name), "dataSet"), "EnforceConstraints"))); enforceConstraintsProperty.SetStatements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(this.Schema.Name), "dataSet"), "EnforceConstraints"), new CodePropertySetValueReferenceExpression())); this.Members.Add(enforceConstraintsProperty); // /// <summary> // /// Gets the collection of tables contained in the DataModel. // /// </summary> // [System.ComponentModel.Browsable(false)] // [System.ComponentModel.DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Content)] // public static TableCollection Tables // { // get // { // return new TableCollection(DataModel.dataSet.Tables); // } // } CodeMemberProperty tablesProperty = new CodeMemberProperty(); tablesProperty.Comments.Add(new CodeCommentStatement("<summary>", true)); tablesProperty.Comments.Add(new CodeCommentStatement(string.Format("Gets the collection of tables contained in the {0}.", this.Schema.Name), true)); tablesProperty.Comments.Add(new CodeCommentStatement("</summary>", true)); tablesProperty.CustomAttributes.Add(new CodeAttributeDeclaration("System.ComponentModel.Browsable", new CodeAttributeArgument[] { new CodeAttributeArgument(new CodePrimitiveExpression(false)) })); tablesProperty.CustomAttributes.Add(new CodeAttributeDeclaration("System.ComponentModel.DesignerSerializationVisibilityAttribute", new CodeAttributeArgument[] { new CodeAttributeArgument(new CodeTypeReferenceExpression("System.ComponentModel.DesignerSerializationVisibility.Content")) })); tablesProperty.Attributes = MemberAttributes.Public | MemberAttributes.Static; tablesProperty.Type = new CodeTypeReference("TableCollection"); tablesProperty.Name = "Tables"; tablesProperty.GetStatements.Add(new CodeMethodReturnStatement(new CodeObjectCreateExpression("TableCollection", new CodeExpression[] { new CodeFieldReferenceExpression(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(this.Schema.Name), "dataSet"), "Tables") }))); this.Members.Add(tablesProperty); // /// <summary> // /// Gets the collection of relations that link tables and allow navigation between parent tables and child tables. // /// </summary> // [System.ComponentModel.Browsable(false)] // [System.ComponentModel.DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Content)] // public static RelationCollection Relations // { // get // { // return new RelationCollection(DataModel.dataSet.Relations); // } // } CodeMemberProperty relationsProperty = new CodeMemberProperty(); relationsProperty.Comments.Add(new CodeCommentStatement("<summary>", true)); relationsProperty.Comments.Add(new CodeCommentStatement("Gets the collection of relations that link tables and allow navigation between parent tables and child tables.", true)); relationsProperty.Comments.Add(new CodeCommentStatement("</summary>", true)); relationsProperty.CustomAttributes.Add(new CodeAttributeDeclaration("System.ComponentModel.Browsable", new CodeAttributeArgument[] { new CodeAttributeArgument(new CodePrimitiveExpression(false)) })); relationsProperty.CustomAttributes.Add(new CodeAttributeDeclaration("System.ComponentModel.DesignerSerializationVisibilityAttribute", new CodeAttributeArgument[] { new CodeAttributeArgument(new CodeTypeReferenceExpression("System.ComponentModel.DesignerSerializationVisibility.Content")) })); relationsProperty.Attributes = MemberAttributes.Public | MemberAttributes.Static; relationsProperty.Type = new CodeTypeReference("RelationCollection"); relationsProperty.Name = "Relations"; relationsProperty.GetStatements.Add(new CodeMethodReturnStatement(new CodeObjectCreateExpression("RelationCollection", new CodeExpression[] { new CodeFieldReferenceExpression(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(this.Schema.Name), "dataSet"), "Relations") }))); this.Members.Add(relationsProperty); // /// <summary> // /// Gets an accessor for the Department table. // /// </summary> // [System.ComponentModel.Browsable(false)] // [System.ComponentModel.DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Content)] // public static DepartmentDataTable Department // { // get // { // return DataModel.tableDepartment; // } // } foreach (TableSchema tableSchema in this.Schema.Tables) { CodeMemberProperty codeMemberProperty = new CodeMemberProperty(); codeMemberProperty.Comments.Add(new CodeCommentStatement("<summary>", true)); codeMemberProperty.Comments.Add(new CodeCommentStatement(string.Format("Gets an accessor for the {0} table.", tableSchema.Name), true)); codeMemberProperty.Comments.Add(new CodeCommentStatement("</summary>", true)); codeMemberProperty.CustomAttributes.Add(new CodeAttributeDeclaration("System.ComponentModel.Browsable", new CodeAttributeArgument[] { new CodeAttributeArgument(new CodePrimitiveExpression(false)) })); codeMemberProperty.CustomAttributes.Add(new CodeAttributeDeclaration("System.ComponentModel.DesignerSerializationVisibilityAttribute", new CodeAttributeArgument[] { new CodeAttributeArgument(new CodeTypeReferenceExpression("System.ComponentModel.DesignerSerializationVisibility.Content")) })); codeMemberProperty.Attributes = MemberAttributes.Public | MemberAttributes.Final | MemberAttributes.Static; codeMemberProperty.Type = new CodeTypeReference(string.Format("{0}DataTable", tableSchema.Name)); codeMemberProperty.Name = tableSchema.Name; codeMemberProperty.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(this.Schema.Name), string.Format("table{0}", tableSchema.Name)))); this.Members.Add(codeMemberProperty); } // /// <summary> // /// Dispose of an instance of the DataModel. // /// </summary> // protected override void Dispose(bool disposing) // { // // This section disposes of the managed resources. // if ((disposing == true)) // { // // This controls the disposal of the static resources. When the instance count reaches zero, then all static resources // // should be released back to the operating system. // DataModel.referenceCount = (DataModel.referenceCount - 1); // } // // Allow the base class to complete the disposal. // base.Dispose(disposing); // } CodeMemberMethod disposeMethod = new CodeMemberMethod(); disposeMethod.Comments.Add(new CodeCommentStatement("<summary>", true)); disposeMethod.Comments.Add(new CodeCommentStatement(string.Format("Dispose of an instance of the {0}.", this.Schema.Name), true)); disposeMethod.Comments.Add(new CodeCommentStatement("</summary>", true)); disposeMethod.Name = "Dispose"; disposeMethod.Attributes = MemberAttributes.Override | MemberAttributes.Family; disposeMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(System.Boolean), "disposing")); disposeMethod.Statements.Add(new CodeCommentStatement("This section disposes of the managed resources.")); CodeStatement[] disposeMethodTrue = new CodeStatement[] { new CodeCommentStatement("This controls the disposal of the static resources. When the instance count reaches zero, then all static resources"), new CodeCommentStatement("should be released back to the operating system."), new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(this.Schema.Name), "referenceCount"), new CodeBinaryOperatorExpression(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(this.Schema.Name), "referenceCount"), CodeBinaryOperatorType.Subtract, new CodePrimitiveExpression(1))) }; disposeMethod.Statements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodeArgumentReferenceExpression("disposing"), CodeBinaryOperatorType.IdentityEquality, new CodePrimitiveExpression(true)), disposeMethodTrue)); disposeMethod.Statements.Add(new CodeCommentStatement("Allow the base class to complete the disposal.")); disposeMethod.Statements.Add(new CodeMethodInvokeExpression(new CodeBaseReferenceExpression(), "Dispose", new CodeArgumentReferenceExpression("disposing"))); this.Members.Add(disposeMethod); // /// <summary> // /// Commits all the changes that were made to this DataModel since the last time DataModel.AcceptChanges was called. // /// </summary> // public static void AcceptChanges() // { // // Commit the changes. // DataModel.dataSet.AcceptChanges(); // } CodeMemberMethod acceptChangesMethod = new CodeMemberMethod(); acceptChangesMethod.Comments.Add(new CodeCommentStatement("<summary>", true)); acceptChangesMethod.Comments.Add(new CodeCommentStatement(string.Format("Commits all the changes that were made to this {0} since the last time {0}.AcceptChanges was called.", this.Schema.Name), true)); acceptChangesMethod.Comments.Add(new CodeCommentStatement("</summary>", true)); acceptChangesMethod.Name = "AcceptChanges"; acceptChangesMethod.Attributes = MemberAttributes.Final | MemberAttributes.Static | MemberAttributes.Public; acceptChangesMethod.Statements.Add(new CodeCommentStatement("Commit the changes.")); acceptChangesMethod.Statements.Add(new CodeMethodInvokeExpression(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(this.Schema.Name), "dataSet"), "AcceptChanges", new CodeExpression[] {})); this.Members.Add(acceptChangesMethod); // /// <summary> // /// Clears the DataModel of any data by removing all rows in a table. // /// </summary> // public static void Clear() // { // // Clear the DataModel. // DataModel.dataSet.Clear(); // } CodeMemberMethod clearMethod = new CodeMemberMethod(); clearMethod.Comments.Add(new CodeCommentStatement("<summary>", true)); clearMethod.Comments.Add(new CodeCommentStatement(string.Format("Clears the {0} of any data by removing all rows in a table.", this.Schema.Name), true)); clearMethod.Comments.Add(new CodeCommentStatement("</summary>", true)); clearMethod.Name = "Clear"; clearMethod.Attributes = MemberAttributes.Final | MemberAttributes.Static | MemberAttributes.Public; clearMethod.Statements.Add(new CodeCommentStatement(string.Format("Clear the {0}.", this.Schema.Name))); clearMethod.Statements.Add(new CodeMethodInvokeExpression(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(this.Schema.Name), "dataSet"), "Clear", new CodeExpression[] { })); this.Members.Add(clearMethod); // /// <summary> // /// Gets the instance of the data model. // /// </summary> // public static System.Data.DataSet GetDataSet() // { // // This is used by the ADO Resource Manager to identify the instance of the data model. // return DataModel.dataSet; // } CodeMemberMethod getDataModelMethod = new CodeMemberMethod(); this.Members.Add(getDataModelMethod); getDataModelMethod.Comments.Add(new CodeCommentStatement("<summary>", true)); getDataModelMethod.Comments.Add(new CodeCommentStatement("Gets the instance of the data model.", true)); getDataModelMethod.Comments.Add(new CodeCommentStatement("</summary>", true)); getDataModelMethod.Name = "GetDataSet"; getDataModelMethod.ReturnType = new CodeTypeReference(typeof(System.Data.DataSet)); getDataModelMethod.Attributes = MemberAttributes.Final | MemberAttributes.Static | MemberAttributes.Public; getDataModelMethod.Statements.Add(new CodeCommentStatement("This is used by the ADO Resource Manager to identify the instance of the data model.")); getDataModelMethod.Statements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(this.Schema.Name), "dataSet"))); // /// <summary> // /// Delegate for handling changes to the Department table. // /// </summary> // /// <param name="sender">The object that originated the event.</param> // /// <param name="e">The event arguments.</param> // public delegate void DepartmentRowChangeEventHandler(object sender, DepartmentRowChangeEvent e); foreach (TableSchema tableSchema in this.Schema.Tables) { CodeTypeDelegate codeTypeDelegate = new CodeTypeDelegate(); codeTypeDelegate.Comments.Add(new CodeCommentStatement("<summary>", true)); codeTypeDelegate.Comments.Add(new CodeCommentStatement(string.Format("Delegate for handling changes to the {0} table.", tableSchema.Name), true)); codeTypeDelegate.Comments.Add(new CodeCommentStatement("</summary>", true)); codeTypeDelegate.Comments.Add(new CodeCommentStatement("<param name=\"sender\">The object that originated the event.</param>", true)); codeTypeDelegate.Comments.Add(new CodeCommentStatement("<param name=\"e\">The event arguments.</param>", true)); codeTypeDelegate.Name = String.Format("{0}RowChangeEventHandler", tableSchema.Name); codeTypeDelegate.ReturnType = new CodeTypeReference(typeof(void)); codeTypeDelegate.TypeAttributes = System.Reflection.TypeAttributes.Public; codeTypeDelegate.Parameters.AddRange(new CodeParameterDeclarationExpression[] { new CodeParameterDeclarationExpression(typeof(System.Object), "sender"), new CodeParameterDeclarationExpression(String.Format("{0}RowChangeEvent", tableSchema.Name), "e") }); this.Members.Add(codeTypeDelegate); } // This will create the strongly typed table, indices, rows and event handlers for each of the tables in the schema. foreach (TableSchema tableSchema in this.Schema.Tables) { // Add a strongly typed definition for each of the tables to the data model class. this.Members.Add(new TypedTableClass(tableSchema)); // Add a strongly typed index for each of the keys on the table. foreach (ConstraintSchema constraintSchema in tableSchema.Keys) { if (constraintSchema.IsPrimaryKey) { this.Members.Add(new TypedPrimaryIndexClass(constraintSchema)); } else { this.Members.Add(new TypedIndexClass(constraintSchema)); } } // Create the strongly typed rows of the table. this.Members.Add(new TypedRowClass(tableSchema)); // Create the strongly typed event handlers for the table. this.Members.Add(new TypedChangeEventArgsClass(tableSchema)); } }