/// <summary> /// Creates a property that is a foreign key within the current table that points to a primary key in another table. These typically have BelongsTo attributes. /// </summary> /// <param name="classDeclaration">The class to which the property is added.</param> /// <param name="foreignKey">The foreign key the property represents.</param> /// <returns>The foreign key property that was added.</returns> protected override PropertyDeclaration CreateForeignKey(ClassDeclaration classDeclaration, ForeignKeyColumnSchema foreignKey) { string fkname = this.NameProvider.GetPropertyName(foreignKey); string fkfieldname = this.NameProvider.GetFieldName(foreignKey); string fkdatatype = this.NameProvider.GetClassName(foreignKey.PrimaryKeyTable); PropertyDeclaration result = classDeclaration.AddProperty(fkname, fkfieldname, fkdatatype); result.AddAttribute("Castle.ActiveRecord.BelongsToAttribute").AddQuotedArgument(foreignKey.Name); return result; }
/// <summary> /// Creates a property that has a HasManyAttribute. /// </summary> /// <param name="classDecl">The class containing the property.</param> /// <param name="foreignkey">The foreign key to use.</param> /// <returns>A prpoerty with a hasmany attribute.</returns> protected override PropertyDeclaration CreateForeignKeyReference(ClassDeclaration classDecl, ForeignKeyColumnSchema foreignkey) { PropertyDeclaration fk = base.CreateForeignKeyReference(classDecl, foreignkey); if (fk == null) return null; AttributeDeclaration hasmany = fk.Attributes.Find(delegate(AttributeDeclaration attr) { return attr.TypeReference.IsTypeOf("Castle.ActiveRecord.HasManyAttribute"); }); if (hasmany != null) hasmany.AddArgument("Lazy=true, Inverse=false"); return fk; }
/// <summary> /// Creates a property that has many children that point to the primary key contained within this class. Typically these will have HasMany attributes. /// </summary> /// <param name="classDeclaration">The class to which the property is added.</param> /// <param name="foreignKey">The foreign key in the table that references the primary key in this class.</param> /// <returns>The property that was added.</returns> protected override PropertyDeclaration CreateForeignKeyReference(ClassDeclaration classDeclaration, ForeignKeyColumnSchema foreignKey) { if (foreignKey.Table.PrimaryKey == null) return null; string propertyName = this.NameProvider.GetListPropertyName(foreignKey); string fieldName = this.NameProvider.GetListFieldName(foreignKey); string typeParam = this.NameProvider.GetClassName(foreignKey.Table); CodeDomTypeReference genericList = new CodeDomTypeReference("System.Collections.Generic.List").AddTypeParameters(typeParam); PropertyDeclaration result = classDeclaration.AddProperty(propertyName, fieldName, "System.Collections.Generic.IList"); result.InitializeField(genericList) .AddTypeParameter(typeParam) .AddAttribute("Castle.ActiveRecord.HasManyAttribute") .AddArgument("typeof(" + this.NameProvider.GetClassName(foreignKey.Table) + ")"); return result; }
protected override PropertyDeclaration CreateForeignKey(ClassDeclaration classDeclaration, ForeignKeyColumnSchema foreignKey) { string columnName = foreignKey.PrimaryKeyTable.Name; string fkname = this.NameProvider.GetPropertyName(columnName); string fkfieldname = this.NameProvider.GetFieldName(columnName); string fkdatatype = this.NameProvider.GetClassName(foreignKey.PrimaryKeyTable); //add the field var field = new CodeMemberField(fkdatatype, fkfieldname); classDeclaration.Members.Add(field); //add the prop var prop = new CodeMemberProperty(); prop.Name = fkname; prop.Type = new CodeTypeReference(fkdatatype); prop.Attributes = MemberAttributes.Public | MemberAttributes.Final; prop.GetStatements.Add( new CodeMethodReturnStatement( new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fkfieldname))); //if (value == null || this._stateCode == null || (value.ID != this._stateCode.ID)) var ifValueNull = new CodeBinaryOperatorExpression(new CodeSnippetExpression("value"), CodeBinaryOperatorType.IdentityEquality, new CodeSnippetExpression("null")); var ifFieldNull = new CodeBinaryOperatorExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fkfieldname), CodeBinaryOperatorType.IdentityEquality, new CodeSnippetExpression("null")); var valueIdExpression = new CodePropertyReferenceExpression(new CodeSnippetExpression("value"), "ID"); var fieldIdExpression = new CodePropertyReferenceExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fkfieldname), "ID"); var ifValueIdDoesNotEqualFieldId = new CodeBinaryOperatorExpression(valueIdExpression, CodeBinaryOperatorType.IdentityInequality, fieldIdExpression); prop.SetStatements.Add( new CodeConditionStatement( new CodeBinaryOperatorExpression( new CodeBinaryOperatorExpression(ifValueNull, CodeBinaryOperatorType.BooleanOr, ifFieldNull), CodeBinaryOperatorType.BooleanOr, ifValueIdDoesNotEqualFieldId), new CodeSnippetStatement(String.Format("{1}((EightyProofSolutions.BlogEngine.Core.Models.ITrackPropertyChanges)this).OnPropertyChanged(\"{0}\", this.{2}, value);", fkname, new String('\t', 5), fkfieldname)), new CodeAssignStatement( new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fkfieldname), new CodeSnippetExpression("value")))); classDeclaration.Members.Add(prop); return null; //PropertyDeclaration result = classDeclaration.AddProperty(fkname, fkfieldname, fkdatatype); //return result; }
/// <summary> /// Creates a property that has many children that point to the primary key contained within this class. Typically these will have HasMany attributes. /// </summary> /// <param name="classDecl">The class to which the property is added.</param> /// <param name="foreignKey">The foreign key in the table that references the primary key in this class.</param> /// <returns>The property that was added.</returns> protected override PropertyDeclaration CreateForeignKeyReference(ClassDeclaration classDecl, ForeignKeyColumnSchema foreignKey) { //no foreign key references return null; }
/// <summary> /// Gets all of the foreign keys within a table. /// </summary> /// <param name="table"></param> /// <returns></returns> public virtual ForeignKeyColumnSchemaList GetForeignKeys(TableSchema table) { ForeignKeyColumnSchemaList result = new ForeignKeyColumnSchemaList(); string cmdtext = @" select distinct col_name(fc.parent_object_id, fc.parent_column_id) as column_name, c.data_type, object_name (f.referenced_object_id) as primary_key_table, c.* from sys.foreign_keys as f inner join sys.foreign_key_columns as fc on f.object_id = fc.constraint_object_id inner join information_schema.columns c on c.column_name = col_name(fc.parent_object_id, fc.parent_column_id) and c.table_name = object_name(f.parent_object_id) where object_name(f.parent_object_id) = @table_name "; using (SqlCommand cmd = new SqlCommand(cmdtext)) { cmd.Parameters.Add("@table_name", SqlDbType.NVarChar, 128).Value = table.Name; using (IDataReader reader = this._helper.ExecuteReader(cmd)) { while (reader.Read()) { string columnName = reader["column_name"].ToString(); SqlDbType sqldatatype = Enum<SqlDbType>.Parse(reader["data_type"].ToString()); Type datatype = getDataType(reader["data_type"].ToString()); Dictionary<string, object> props = new Dictionary<string, object>(); props.Add("primary_key_table", reader["primary_key_table"].ToString()); int length = reader["CHARACTER_MAXIMUM_LENGTH"] != DBNull.Value ? System.Convert.ToInt32(reader["CHARACTER_MAXIMUM_LENGTH"]) : -1; ForeignKeyColumnSchema column = new ForeignKeyColumnSchema(this, table, sqldatatype, datatype, columnName, length, props); result.Add(column); } } } return result; }
/// <summary> /// Creates a property that has many children that point to the primary key contained within this class. Typically these will have HasMany attributes. /// </summary> /// <param name="classDecl">The class to which the property is added.</param> /// <param name="foreignKey">The foreign key in the table that references the primary key in this class.</param> /// <returns>The property that was added.</returns> protected abstract PropertyDeclaration CreateForeignKeyReference(ClassDeclaration classDecl, ForeignKeyColumnSchema foreignKey);
protected override PropertyDeclaration CreateForeignKeyReference(ClassDeclaration classDeclaration, ForeignKeyColumnSchema foreignKey) { if (foreignKey.Table.PrimaryKey == null) return null; string propertyName = this.NameProvider.GetListPropertyName(foreignKey); string fieldName = this.NameProvider.GetListFieldName(foreignKey); string typeParam = this.NameProvider.GetClassName(foreignKey.Table); CodeDomTypeReference genericList = new CodeDomTypeReference("System.Collections.Generic.List").AddTypeParameters(typeParam); //create the field classDeclaration.Members.Add(new CodeMemberField(genericList.ToCodeDom(), fieldName)); //create the prop var prop = new CodeMemberProperty(); prop.Name = propertyName; prop.Type = genericList.ToCodeDom(); prop.Attributes = MemberAttributes.Final | MemberAttributes.Public; prop.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fieldName))); prop.SetStatements.Add( new CodeConditionStatement( new CodeBinaryOperatorExpression( new CodeSnippetExpression("value"), CodeBinaryOperatorType.IdentityInequality, new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fieldName)), new CodeSnippetStatement(String.Format("{1}((EightyProofSolutions.BlogEngine.Core.Models.ITrackPropertyChanges)this).OnPropertyChanged(\"{0}\", this.{2}, value);", propertyName, new String('\t', 5), fieldName)), new CodeAssignStatement( new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fieldName), new CodeSnippetExpression("value")))); classDeclaration.Members.Add(prop); return null; }
/// <summary> /// Gets a foreign key property name. The default implementation removes _id from the end of the /// foreignkey name and returns the result of passing that value to GetPropertyName. /// </summary> /// <param name="foreignkey">The foreign key that will supply the database name to format.</param> /// <returns>The forign key name formatted as a property name.</returns> public virtual string GetPropertyName(ForeignKeyColumnSchema foreignkey) { return this.GetPropertyName(foreignkey.Name.Replace("_id", "")); }
/// <summary> /// Gets a property name derived from a foreign key reference. The default implementation returns /// the pluralized, pascalized version of the foreign key table name. /// </summary> /// <param name="foreignkey">The foreign key.</param> /// <returns>The property name derived from the foreign key.</returns> public virtual string GetListPropertyName(ForeignKeyColumnSchema foreignkey) { return this.GetPropertyName(Inflector.Pluralize(this.GetClassName(foreignkey.Table.Name.Replace(foreignkey.PrimaryKeyTable.Name, "")))); }
/// <summary> /// Gets a field name derived from a foreign key reference. /// </summary> /// <param name="foreignkey">The foreign key being referenced</param> /// <returns>The field name.</returns> public virtual string GetListFieldName(ForeignKeyColumnSchema foreignkey) { return this.GetFieldName(Inflector.Pluralize(ScrubPrefix(foreignkey.Table.Name))); }