private static bool IsTableKeySchemaCascadeDelete(TableKeySchema tableKeySchema) { return(tableKeySchema.ExtendedProperties.Contains("CS_CascadeDelete") && tableKeySchema.ExtendedProperties["CS_CascadeDelete"].Value != null && tableKeySchema.ExtendedProperties["CS_CascadeDelete"].Value is Boolean && (bool)tableKeySchema.ExtendedProperties["CS_CascadeDelete"].Value); }
public TableKeySchema[] GetTableKeys(string connectionString, TableSchema table) { //0, 2, 3; catalog, table, key name DataTable dt = GetSchemaData(connectionString, ForeignKeys, null /*restrictions[0] - catalog*/, null /*restrictions[1] - unused*/, table.Name /*restrictions[2] - table*/, null /*restrictions[3] - key name*/); TableKeySchema[] keys = new TableKeySchema[dt.Rows.Count]; int keyIdx = 0; foreach (DataRow dr in dt.Rows) { TableKeySchema key = new TableKeySchema(table.Database, (String)dr[ForeignKeysNameColumn], new string[] { (String)dr[ForeignKeysFromColColumn] }, (String)dr[ForeignKeysFromTableColumn], new string[] { (String)dr[ForeignKeysToColColumn] }, (String)dr[ForeignKeysToTableColumn]); keys[keyIdx++] = key; } return(keys); }
/// <summary> /// DeleteOnNull deletes an entity when a Associated Property on that entity is /// set to null and the Foreign Key for that association does not allow nulls. /// /// Should return true when all of the following conditions are met... /// A) A Foreign Key column on the entity does not allow null values. /// B) All dependancies on that entity will do a cascade delete. /// </summary> /// <param name="tableKeySchema">TableKeySchema.ForeignKeyTable is the table being analyzed.</param> /// <returns>Value of AssociationAttribute DeleteOnNull Property</returns> private static bool IsTableDeleteOnNull(TableKeySchema tableKeySchema) { bool foreignTableForeignKeyColumnAllowDBNull = (tableKeySchema.ForeignKeyMemberColumns.Count == 0); foreach (MemberColumnSchema foreignColumn in tableKeySchema.ForeignKeyMemberColumns) { if (foreignColumn.AllowDBNull) { foreignTableForeignKeyColumnAllowDBNull = true; break; } } if (foreignTableForeignKeyColumnAllowDBNull) { return(false); } bool foreignTablePrimaryKeysCascadeDelete = true; foreach (TableKeySchema foreignTableKeySchema in tableKeySchema.ForeignKeyTable.PrimaryKeys) { if (IsTableKeySchemaCascadeDelete(foreignTableKeySchema)) { foreignTablePrimaryKeysCascadeDelete = false; break; } } return(foreignTablePrimaryKeysCascadeDelete); }
public TableKeySchema[] GetTableKeys(string connectionString, TableSchema table) { if (_cachedConnectionString != connectionString) { _cachedConnectionString = connectionString; _doc.Load(connectionString); } XmlNodeList foreignKeys = _doc.SelectNodes("dcl:schema/dcl:table[@name='" + table.Name + "']/dcl:referenceConstraint|dcl:schema/dcl:table/dcl:referenceConstraint[@targetTable='" + table.Name + "']", _manager); int foreignKeyCount = foreignKeys.Count; TableKeySchema[] ret = new TableKeySchema[foreignKeyCount]; for (int i = 0; i < foreignKeyCount; ++i) { XmlNode foreignKey = foreignKeys[i]; string foreignKeyName = "", foreignKeyTable = "", primaryKeyTable = ""; string[] foreignKeyColumns, primaryKeyColumns; XmlAttribute foreignKeyTableNode = foreignKey.ParentNode.Attributes["name"]; if (foreignKeyTableNode != null) { foreignKeyTable = foreignKeyTableNode.Value; } XmlAttribute primaryKeyTableNode = foreignKey.Attributes["targetTable"]; if (primaryKeyTableNode != null) { primaryKeyTable = primaryKeyTableNode.Value; } XmlAttribute foreignKeyNameNode = foreignKey.Attributes["name"]; if (foreignKeyNameNode != null) { foreignKeyName = foreignKeyNameNode.Value; } XmlNodeList columnRefNodeList = foreignKey.SelectNodes("dcl:columnRef", _manager); int columnRefNodeListCount = columnRefNodeList.Count; foreignKeyColumns = new string[columnRefNodeListCount]; primaryKeyColumns = new string[columnRefNodeListCount]; for (int j = 0; j < columnRefNodeListCount; ++j) { XmlNode columnRefNode = columnRefNodeList[j]; XmlAttribute sourceNameAttribute = columnRefNode.Attributes["sourceName"]; if (sourceNameAttribute != null) { foreignKeyColumns[j] = sourceNameAttribute.Value; } XmlAttribute targetNameAttribute = columnRefNode.Attributes["targetName"]; if (targetNameAttribute != null) { primaryKeyColumns[j] = targetNameAttribute.Value; } } ret[i] = new TableKeySchema(table.Database, foreignKeyName, foreignKeyColumns, foreignKeyTable, primaryKeyColumns, primaryKeyTable); } return(ret); }
private void CompareForeignKeys(ForeignKey foreignKey, TableKeySchema tableKeySchema) { Assert.AreEqual(1, tableKeySchema.ForeignKeyMemberColumns.Count); Assert.AreEqual(foreignKey.FromColumn, tableKeySchema.ForeignKeyMemberColumns[0].Name); Assert.AreEqual(foreignKey.ToTable, tableKeySchema.PrimaryKeyTable.Name); Assert.AreEqual(1, tableKeySchema.PrimaryKeyMemberColumns.Count); Assert.AreEqual(foreignKey.ToColumn, tableKeySchema.PrimaryKeyMemberColumns[0].Name); }
private static bool IsOneToOne(TableKeySchema tableKeySchema, Relationship foreignRelationship) { bool isFkeyPkey = tableKeySchema.ForeignKeyTable.HasPrimaryKey && tableKeySchema.ForeignKeyTable.PrimaryKey != null && tableKeySchema.ForeignKeyTable.PrimaryKey.MemberColumns.Count == 1 && tableKeySchema.ForeignKeyTable.PrimaryKey.MemberColumns.Contains( foreignRelationship.ThisProperties.FirstOrDefault()); if (isFkeyPkey) { return(true); } // if f.key is unique return(tableKeySchema.ForeignKeyMemberColumns.All(column => column.IsUnique)); }
private static bool IsOneToOne(TableKeySchema tableKeySchema, Association foreignAssociation) { bool isFkeyPkey = tableKeySchema.ForeignKeyTable.HasPrimaryKey && tableKeySchema.ForeignKeyTable.PrimaryKey != null && tableKeySchema.ForeignKeyTable.PrimaryKey.MemberColumns.Count == 1 && tableKeySchema.ForeignKeyTable.PrimaryKey.MemberColumns.Contains(foreignAssociation.ThisKey); if (isFkeyPkey) { return(true); } // if f.key is unique foreach (var column in tableKeySchema.ForeignKeyMemberColumns) { if (!column.IsUnique) { return(false); } } return(true); }
private void CreateAssociation(Table foreignTable, TableKeySchema tableKeySchema) { if (Settings.IsIgnored(tableKeySchema.PrimaryKeyTable.FullName)) { Debug.WriteLine("Skipping Association because one of the tables is skipped: " + tableKeySchema.Name); Trace.WriteLine("Skipping Association because one of the tables is skipped: " + tableKeySchema.Name); return; } // skip unsupported type if (tableKeySchema.ForeignKeyMemberColumns.Any(c => Settings.IsUnsupportedDbType(c)) || tableKeySchema.PrimaryKeyMemberColumns.Any(c => Settings.IsUnsupportedDbType(c))) { Debug.WriteLine("Skipping Association because one of the associated columns is an unsupported db type: " + tableKeySchema.Name); Trace.WriteLine("Skipping Association because one of the associated columns is an unsupported db type: " + tableKeySchema.Name); return; } Table primaryTable = GetTable(tableKeySchema.PrimaryKeyTable, false); string primaryClass = primaryTable.Type.Name; string foreignClass = foreignTable.Type.Name; string name = string.Format("{0}_{1}", primaryClass, foreignClass); name = MakeUnique(AssociationNames, name); string foreignMembers = GetKeyMembers(foreignTable, tableKeySchema.ForeignKeyMemberColumns, tableKeySchema.Name); string primaryMembers = GetKeyMembers(primaryTable, tableKeySchema.PrimaryKeyMemberColumns, tableKeySchema.Name); AssociationKey key = AssociationKey.CreateForeignKey(name); bool isNew = !foreignTable.Type.Associations.Contains(key); Association foreignAssociation; if (isNew) foreignAssociation = new Association(name); else foreignAssociation = foreignTable.Type.Associations[key]; foreignAssociation.IsForeignKey = true; foreignAssociation.ThisKey = foreignMembers; foreignAssociation.OtherKey = primaryMembers; foreignAssociation.Type = primaryClass; string prefix = GetMemberPrefix(foreignAssociation, primaryClass, foreignClass); if (isNew) { foreignAssociation.Member = ToPropertyName(foreignTable.Type.Name, prefix + primaryClass); foreignAssociation.Storage = CommonUtility.GetFieldName(foreignAssociation.Member); foreignTable.Type.Associations.Add(foreignAssociation); } else { PropertyNames[foreignTable.Type.Name].Add(foreignAssociation.Member); } // add reverse association key = AssociationKey.CreatePrimaryKey(name); isNew = !primaryTable.Type.Associations.Contains(key); Association primaryAssociation; if (isNew) primaryAssociation = new Association(name); else primaryAssociation = primaryTable.Type.Associations[key]; primaryAssociation.IsForeignKey = false; primaryAssociation.ThisKey = foreignAssociation.OtherKey; primaryAssociation.OtherKey = foreignAssociation.ThisKey; primaryAssociation.Type = foreignClass; bool isOneToOne = IsOneToOne(tableKeySchema, foreignAssociation); if (primaryAssociation.Cardinality == null && isOneToOne) primaryAssociation.Cardinality = Cardinality.One; if (isNew) { string propertyName = prefix + foreignClass; if (!isOneToOne) { if (settings.AssociationNaming == AssociationNamingEnum.ListSuffix) propertyName += "List"; else if (settings.AssociationNaming == AssociationNamingEnum.Plural) propertyName = StringUtil.ToPlural(propertyName); } primaryAssociation.Member = ToPropertyName(primaryTable.Type.Name, propertyName); primaryAssociation.Storage = CommonUtility.GetFieldName(primaryAssociation.Member); primaryTable.Type.Associations.Add(primaryAssociation); } else { PropertyNames[primaryTable.Type.Name].Add(primaryAssociation.Member); } if (IsTableKeySchemaCascadeDelete(tableKeySchema)) { foreignAssociation.DeleteRule = "CASCADE"; } if (settings.IncludeDeleteOnNull || foreignTable.Type.IsManyToMany()) { if (!foreignAssociation.DeleteOnNull.HasValue && IsTableDeleteOnNull(tableKeySchema)) foreignAssociation.DeleteOnNull = true; } else foreignAssociation.DeleteOnNull = null; foreignAssociation.IsProcessed = true; primaryAssociation.IsProcessed = true; }
private void CreateAssociation(Table foreignTable, TableKeySchema tableKeySchema) { if (Settings.IsIgnored(tableKeySchema.PrimaryKeyTable.FullName)) { Debug.WriteLine("Skipping Association because one of the tables is skipped: " + tableKeySchema.Name); Trace.WriteLine("Skipping Association because one of the tables is skipped: " + tableKeySchema.Name); return; } // skip unsupported type if (tableKeySchema.ForeignKeyMemberColumns.Any(c => Settings.IsUnsupportedDbType(c)) || tableKeySchema.PrimaryKeyMemberColumns.Any(c => Settings.IsUnsupportedDbType(c))) { Debug.WriteLine("Skipping Association because one of the associated columns is an unsupported db type: " + tableKeySchema.Name); Trace.WriteLine("Skipping Association because one of the associated columns is an unsupported db type: " + tableKeySchema.Name); return; } Table primaryTable = GetTable(tableKeySchema.PrimaryKeyTable, false); string primaryClass = primaryTable.Type.Name; string foreignClass = foreignTable.Type.Name; string name = string.Format("{0}_{1}", primaryClass, foreignClass); name = MakeUnique(AssociationNames, name); string foreignMembers = GetKeyMembers(foreignTable, tableKeySchema.ForeignKeyMemberColumns, tableKeySchema.Name); string primaryMembers = GetKeyMembers(primaryTable, tableKeySchema.PrimaryKeyMemberColumns, tableKeySchema.Name); AssociationKey key = AssociationKey.CreateForeignKey(name); bool isNew = !foreignTable.Type.Associations.Contains(key); Association foreignAssociation; if (isNew) { foreignAssociation = new Association(name); } else { foreignAssociation = foreignTable.Type.Associations[key]; } foreignAssociation.IsForeignKey = true; foreignAssociation.ThisKey = foreignMembers; foreignAssociation.OtherKey = primaryMembers; foreignAssociation.Type = primaryClass; string prefix = GetMemberPrefix(foreignAssociation, primaryClass, foreignClass); if (isNew) { foreignAssociation.Member = ToPropertyName(foreignTable.Type.Name, prefix + primaryClass); foreignAssociation.Storage = CommonUtility.GetFieldName(foreignAssociation.Member); foreignTable.Type.Associations.Add(foreignAssociation); } else { PropertyNames[foreignTable.Type.Name].Add(foreignAssociation.Member); } // add reverse association key = AssociationKey.CreatePrimaryKey(name); isNew = !primaryTable.Type.Associations.Contains(key); Association primaryAssociation; if (isNew) { primaryAssociation = new Association(name); } else { primaryAssociation = primaryTable.Type.Associations[key]; } primaryAssociation.IsForeignKey = false; primaryAssociation.ThisKey = foreignAssociation.OtherKey; primaryAssociation.OtherKey = foreignAssociation.ThisKey; primaryAssociation.Type = foreignClass; bool isOneToOne = IsOneToOne(tableKeySchema, foreignAssociation); if (primaryAssociation.Cardinality == null && isOneToOne) { primaryAssociation.Cardinality = Cardinality.One; } if (isNew) { string propertyName = prefix + foreignClass; if (!isOneToOne) { if (settings.AssociationNaming == AssociationNamingEnum.ListSuffix) { propertyName += "List"; } else if (settings.AssociationNaming == AssociationNamingEnum.Plural) { propertyName = StringUtil.ToPlural(propertyName); } } primaryAssociation.Member = ToPropertyName(primaryTable.Type.Name, propertyName); primaryAssociation.Storage = CommonUtility.GetFieldName(primaryAssociation.Member); primaryTable.Type.Associations.Add(primaryAssociation); } else { PropertyNames[primaryTable.Type.Name].Add(primaryAssociation.Member); } if (IsTableKeySchemaCascadeDelete(tableKeySchema)) { foreignAssociation.DeleteRule = "CASCADE"; } if (settings.IncludeDeleteOnNull || foreignTable.Type.IsManyToMany()) { if (!foreignAssociation.DeleteOnNull.HasValue && IsTableDeleteOnNull(tableKeySchema)) { foreignAssociation.DeleteOnNull = true; } } else { foreignAssociation.DeleteOnNull = null; } foreignAssociation.IsProcessed = true; primaryAssociation.IsProcessed = true; }
/// <summary> /// DeleteOnNull deletes an entity when a Associated Property on that entity is /// set to null and the Foreign Key for that association does not allow nulls. /// /// Should return true when all of the following conditions are met... /// A) A Foreign Key column on the entity does not allow null values. /// B) All dependancies on that entity will do a cascade delete. /// </summary> /// <param name="tableKeySchema">TableKeySchema.ForeignKeyTable is the table being analyzed.</param> /// <returns>Value of AssociationAttribute DeleteOnNull Property</returns> private static bool IsTableDeleteOnNull(TableKeySchema tableKeySchema) { bool foreignTableForeignKeyColumnAllowDBNull = (tableKeySchema.ForeignKeyMemberColumns.Count == 0); foreach (MemberColumnSchema foreignColumn in tableKeySchema.ForeignKeyMemberColumns) { if (foreignColumn.AllowDBNull) { foreignTableForeignKeyColumnAllowDBNull = true; break; } } if (foreignTableForeignKeyColumnAllowDBNull) return false; bool foreignTablePrimaryKeysCascadeDelete = true; foreach (TableKeySchema foreignTableKeySchema in tableKeySchema.ForeignKeyTable.PrimaryKeys) { if (IsTableKeySchemaCascadeDelete(foreignTableKeySchema)) { foreignTablePrimaryKeysCascadeDelete = false; break; } } return foreignTablePrimaryKeysCascadeDelete; }
private static bool IsTableKeySchemaCascadeDelete(TableKeySchema tableKeySchema) { return (tableKeySchema.ExtendedProperties.Contains("CS_CascadeDelete") && tableKeySchema.ExtendedProperties["CS_CascadeDelete"].Value != null && tableKeySchema.ExtendedProperties["CS_CascadeDelete"].Value is Boolean && (bool)tableKeySchema.ExtendedProperties["CS_CascadeDelete"].Value); }
public override Relationship GetAndCreate(TableKeySchema tableKeySchema) { //获取主键表对应实体 TEntity primaryEntity = EntityContext.Entities.ByTable(tableKeySchema.PrimaryKeyTable.FullName); //主表类名 string primaryName = primaryEntity.ClassName; //外键表名 string foreignName = ForeignEntity.ClassName; //映射名称 string relationshipName = tableKeySchema.Name; //获取唯一映射名称 relationshipName = _content.UniqueNamer.UniqueRelationshipName(relationshipName); //判断是否级联删除 bool isCascadeDelete = _content.IsCascadeDelete(tableKeySchema); bool foreignMembersRequired; bool primaryMembersRequired; //获取外键表所有键属性名称 List <string> foreignMembers = _content.GetKeyMembers(ForeignEntity, tableKeySchema.ForeignKeyMemberColumns, tableKeySchema.Name, out foreignMembersRequired); //获取主表中所有键的成员属性名称 List <string> primaryMembers = _content.GetKeyMembers(primaryEntity, tableKeySchema.PrimaryKeyMemberColumns, tableKeySchema.Name, out primaryMembersRequired); // 过滤没有外键主键的表处理 if (foreignMembers == null || primaryMembers == null) { return(null); } Relationship foreignRelationship = ForeignEntity.Relationships .FirstOrDefault(r => r.RelationshipName == relationshipName && r.IsForeignKey); if (foreignRelationship == null) { foreignRelationship = new Relationship { RelationshipName = relationshipName }; ForeignEntity.Relationships.Add(foreignRelationship); } foreignRelationship.IsMapped = true; foreignRelationship.IsForeignKey = true; foreignRelationship.ThisCardinality = foreignMembersRequired ? Cardinality.One : Cardinality.ZeroOrOne; foreignRelationship.ThisEntity = foreignName; foreignRelationship.ThisProperties = new List <string>(foreignMembers); foreignRelationship.OtherEntity = primaryName; foreignRelationship.OtherProperties = new List <string>(primaryMembers); foreignRelationship.CascadeDelete = isCascadeDelete; string prefix = _content.GetMemberPrefix(foreignRelationship, primaryName, foreignName); string foreignPropertyName = _content.ToPropertyName(ForeignEntity.ClassName, prefix + primaryName); foreignPropertyName = _content.UniqueNamer.UniqueName(ForeignEntity.ClassName, foreignPropertyName); foreignRelationship.ThisPropertyName = foreignPropertyName; // add reverse Relationship primaryRelationship = primaryEntity.Relationships .FirstOrDefault(r => r.RelationshipName == relationshipName && r.IsForeignKey == false); if (primaryRelationship == null) { primaryRelationship = new Relationship { RelationshipName = relationshipName }; primaryEntity.Relationships.Add(primaryRelationship); } primaryRelationship.IsMapped = false; primaryRelationship.IsForeignKey = false; primaryRelationship.ThisEntity = primaryName; primaryRelationship.ThisProperties = new List <string>(primaryMembers); primaryRelationship.OtherEntity = foreignName; primaryRelationship.OtherProperties = new List <string>(foreignMembers); primaryRelationship.CascadeDelete = isCascadeDelete; bool isOneToOne = _content.IsOneToOne(tableKeySchema, foreignRelationship); if (isOneToOne) { primaryRelationship.ThisCardinality = primaryMembersRequired ? Cardinality.One : Cardinality.ZeroOrOne; } else { primaryRelationship.ThisCardinality = Cardinality.Many; } string primaryPropertyName = prefix + foreignName; if (!isOneToOne) { primaryPropertyName = _content.Settings.RelationshipName(primaryPropertyName); } primaryPropertyName = _content.ToPropertyName(primaryEntity.ClassName, primaryPropertyName); primaryPropertyName = _content.UniqueNamer.UniqueName(primaryEntity.ClassName, primaryPropertyName); primaryRelationship.ThisPropertyName = primaryPropertyName; foreignRelationship.OtherPropertyName = primaryRelationship.ThisPropertyName; foreignRelationship.OtherCardinality = primaryRelationship.ThisCardinality; primaryRelationship.OtherPropertyName = foreignRelationship.ThisPropertyName; primaryRelationship.OtherCardinality = foreignRelationship.ThisCardinality; foreignRelationship.IsProcessed = true; primaryRelationship.IsProcessed = true; return(primaryRelationship); }
private static bool IsOneToOne(TableKeySchema tableKeySchema, Association foreignAssociation) { bool isFkeyPkey = tableKeySchema.ForeignKeyTable.HasPrimaryKey && tableKeySchema.ForeignKeyTable.PrimaryKey != null && tableKeySchema.ForeignKeyTable.PrimaryKey.MemberColumns.Count == 1 && tableKeySchema.ForeignKeyTable.PrimaryKey.MemberColumns.Contains(foreignAssociation.ThisKey); if (isFkeyPkey) return true; // if f.key is unique foreach (var column in tableKeySchema.ForeignKeyMemberColumns) if (!column.IsUnique) return false; return true; }
public string GetFKMemberColumns(TableKeySchema fk) { string s=""; for( int j = 0; j < fk.ForeignKeyMemberColumns.Count; j++) { s += GetSqlParameterStatement(fk.ForeignKeyMemberColumns[j]); if (j < fk.ForeignKeyMemberColumns.Count - 1) s += ", \n\t"; } return s; }
private void CreateRelationship(EntityContext entityContext, Entity foreignEntity, TableKeySchema tableKeySchema) { Entity primaryEntity = GetEntity(entityContext, tableKeySchema.PrimaryKeyTable, false, false); string primaryName = primaryEntity.ClassName; string foreignName = foreignEntity.ClassName; string relationshipName = tableKeySchema.Name; relationshipName = _namer.UniqueRelationshipName(relationshipName); bool isCascadeDelete = IsCascadeDelete(tableKeySchema); bool foreignMembersRequired; bool primaryMembersRequired; List<string> foreignMembers = GetKeyMembers(foreignEntity, tableKeySchema.ForeignKeyMemberColumns, tableKeySchema.Name, out foreignMembersRequired); List<string> primaryMembers = GetKeyMembers(primaryEntity, tableKeySchema.PrimaryKeyMemberColumns, tableKeySchema.Name, out primaryMembersRequired); Relationship foreignRelationship = foreignEntity.Relationships .FirstOrDefault(r => r.RelationshipName == relationshipName && r.IsForeignKey); if (foreignRelationship == null) { foreignRelationship = new Relationship { RelationshipName = relationshipName }; foreignEntity.Relationships.Add(foreignRelationship); } foreignRelationship.IsMapped = true; foreignRelationship.IsForeignKey = true; foreignRelationship.ThisCardinality = foreignMembersRequired ? Cardinality.One : Cardinality.ZeroOrOne; foreignRelationship.ThisEntity = foreignName; foreignRelationship.ThisProperties = new List<string>(foreignMembers); foreignRelationship.OtherEntity = primaryName; foreignRelationship.OtherProperties = new List<string>(primaryMembers); foreignRelationship.CascadeDelete = isCascadeDelete; string prefix = GetMemberPrefix(foreignRelationship, primaryName, foreignName); string foreignPropertyName = ToPropertyName(foreignEntity.ClassName, prefix + primaryName); foreignPropertyName = _namer.UniqueName(foreignEntity.ClassName, foreignPropertyName); foreignRelationship.ThisPropertyName = foreignPropertyName; // add reverse Relationship primaryRelationship = primaryEntity.Relationships .FirstOrDefault(r => r.RelationshipName == relationshipName && r.IsForeignKey == false); if (primaryRelationship == null) { primaryRelationship = new Relationship { RelationshipName = relationshipName }; primaryEntity.Relationships.Add(primaryRelationship); } primaryRelationship.IsMapped = false; primaryRelationship.IsForeignKey = false; primaryRelationship.ThisEntity = primaryName; primaryRelationship.ThisProperties = new List<string>(primaryMembers); primaryRelationship.OtherEntity = foreignName; primaryRelationship.OtherProperties = new List<string>(foreignMembers); primaryRelationship.CascadeDelete = isCascadeDelete; primaryRelationship.ThisCardinality = Cardinality.Many; string primaryPropertyName = prefix + foreignName; primaryPropertyName = Settings.RelationshipName(primaryPropertyName); primaryPropertyName = ToPropertyName(primaryEntity.ClassName, primaryPropertyName); primaryPropertyName = _namer.UniqueName(primaryEntity.ClassName, primaryPropertyName); primaryRelationship.ThisPropertyName = primaryPropertyName; foreignRelationship.OtherPropertyName = primaryRelationship.ThisPropertyName; foreignRelationship.OtherCardinality = primaryRelationship.ThisCardinality; primaryRelationship.OtherPropertyName = foreignRelationship.ThisPropertyName; primaryRelationship.OtherCardinality = foreignRelationship.ThisCardinality; foreignRelationship.IsProcessed = true; primaryRelationship.IsProcessed = true; }
public string GetFKMemberColumnsWhere(string tablename, TableKeySchema fk) { string s=""; for( int j = 0; j < fk.ForeignKeyMemberColumns.Count; j++) { s += "[" + tablename + "].["+fk.ForeignKeyMemberColumns[j].Name + "]=@" + fk.ForeignKeyMemberColumns[j].Name ; if (j < fk.ForeignKeyMemberColumns.Count - 1) s += " AND "; } return s; }
public TableKeySchema[] GetTableKeys(string connectionString, TableSchema table) { if (_cachedConnectionString != connectionString) { _cachedConnectionString = connectionString; _doc.Load(connectionString); } XmlNodeList foreignKeys = _doc.SelectNodes("dcl:schema/dcl:table[@name='" + table.Name + "']/dcl:referenceConstraint|dcl:schema/dcl:table/dcl:referenceConstraint[@targetTable='" + table.Name + "']", _manager); int foreignKeyCount = foreignKeys.Count; TableKeySchema[] ret = new TableKeySchema[foreignKeyCount]; for (int i = 0; i < foreignKeyCount; ++i) { XmlNode foreignKey = foreignKeys[i]; string foreignKeyName = "", foreignKeyTable = "", primaryKeyTable = ""; string[] foreignKeyColumns, primaryKeyColumns; XmlAttribute foreignKeyTableNode = foreignKey.ParentNode.Attributes["name"]; if (foreignKeyTableNode != null) { foreignKeyTable = foreignKeyTableNode.Value; } XmlAttribute primaryKeyTableNode = foreignKey.Attributes["targetTable"]; if (primaryKeyTableNode != null) { primaryKeyTable = primaryKeyTableNode.Value; } XmlAttribute foreignKeyNameNode = foreignKey.Attributes["name"]; if (foreignKeyNameNode != null) { foreignKeyName = foreignKeyNameNode.Value; } XmlNodeList columnRefNodeList = foreignKey.SelectNodes("dcl:columnRef", _manager); int columnRefNodeListCount = columnRefNodeList.Count; foreignKeyColumns = new string[columnRefNodeListCount]; primaryKeyColumns = new string[columnRefNodeListCount]; for (int j = 0; j < columnRefNodeListCount; ++j) { XmlNode columnRefNode = columnRefNodeList[j]; XmlAttribute sourceNameAttribute = columnRefNode.Attributes["sourceName"]; if (sourceNameAttribute != null) { foreignKeyColumns[j] = sourceNameAttribute.Value; } XmlAttribute targetNameAttribute = columnRefNode.Attributes["targetName"]; if (targetNameAttribute != null) { primaryKeyColumns[j] = targetNameAttribute.Value; } } ret[i] = new TableKeySchema(table.Database, foreignKeyName, foreignKeyColumns, foreignKeyTable, primaryKeyColumns, primaryKeyTable); } return ret; }
/// <summary> /// Check that a given key has all foreign's columns into the primary key. /// </summary> /// <param name="key">The key to check.</param> public bool IsJunctionKey(TableKeySchema key) { foreach(ColumnSchema col in key.ForeignKeyMemberColumns) { if (!col.IsPrimaryKeyMember) return false; } return true; }
public bool IsRelationOneToOne(TableKeySchema schema) { bool relationOkay = true; for(int i = 0; i < schema.PrimaryKeyMemberColumns.Count; i++) relationOkay = schema.PrimaryKeyMemberColumns[i].IsUnique; for(int i = 0; i < schema.ForeignKeyMemberColumns.Count; i++) relationOkay = schema.ForeignKeyMemberColumns[i].IsUnique; return relationOkay; }
public string GetManyToManyName(TableKeySchema junctionTableKey, string junctionTableName) { return GetManyToManyName(junctionTableKey.ForeignKeyMemberColumns, junctionTableName); }
public string FKColumnName(TableKeySchema fkey) { string Name = String.Empty; for(int x=0;x < fkey.ForeignKeyMemberColumns.Count;x++) { Name += GetPropertyName(fkey.ForeignKeyMemberColumns[x].Name); } return Name; }
private void CreateRelationship(EntityContext entityContext, Entity foreignEntity, TableKeySchema tableKeySchema) { Entity primaryEntity = GetEntity(entityContext, tableKeySchema.PrimaryKeyTable, false, false); string primaryName = primaryEntity.ClassName; string foreignName = foreignEntity.ClassName; string relationshipName = tableKeySchema.Name; relationshipName = _namer.UniqueRelationshipName(relationshipName); bool isCascadeDelete = IsCascadeDelete(tableKeySchema); bool foreignMembersRequired; bool primaryMembersRequired; List <string> foreignMembers = GetKeyMembers(foreignEntity, tableKeySchema.ForeignKeyMemberColumns, tableKeySchema.Name, out foreignMembersRequired); List <string> primaryMembers = GetKeyMembers(primaryEntity, tableKeySchema.PrimaryKeyMemberColumns, tableKeySchema.Name, out primaryMembersRequired); // skip invalid fkeys if (foreignMembers == null || primaryMembers == null) { return; } Relationship foreignRelationship = foreignEntity.Relationships .FirstOrDefault(r => r.RelationshipName == relationshipName && r.IsForeignKey); if (foreignRelationship == null) { foreignRelationship = new Relationship { RelationshipName = relationshipName }; foreignEntity.Relationships.Add(foreignRelationship); } foreignRelationship.IsMapped = true; foreignRelationship.IsForeignKey = true; foreignRelationship.ThisCardinality = foreignMembersRequired ? Cardinality.One : Cardinality.ZeroOrOne; foreignRelationship.ThisEntity = foreignName; foreignRelationship.ThisProperties = new List <string>(foreignMembers); foreignRelationship.OtherEntity = primaryName; foreignRelationship.OtherProperties = new List <string>(primaryMembers); foreignRelationship.CascadeDelete = isCascadeDelete; string prefix = GetMemberPrefix(foreignRelationship, primaryName, foreignName); string foreignPropertyName = ToPropertyName(foreignEntity.ClassName, prefix + primaryName); foreignPropertyName = _namer.UniqueName(foreignEntity.ClassName, foreignPropertyName); foreignRelationship.ThisPropertyName = foreignPropertyName; // add reverse Relationship primaryRelationship = primaryEntity.Relationships .FirstOrDefault(r => r.RelationshipName == relationshipName && r.IsForeignKey == false); if (primaryRelationship == null) { primaryRelationship = new Relationship { RelationshipName = relationshipName }; primaryEntity.Relationships.Add(primaryRelationship); } primaryRelationship.IsMapped = false; primaryRelationship.IsForeignKey = false; primaryRelationship.ThisEntity = primaryName; primaryRelationship.ThisProperties = new List <string>(primaryMembers); primaryRelationship.OtherEntity = foreignName; primaryRelationship.OtherProperties = new List <string>(foreignMembers); primaryRelationship.CascadeDelete = isCascadeDelete; bool isOneToOne = IsOneToOne(tableKeySchema, foreignRelationship); if (isOneToOne) { primaryRelationship.ThisCardinality = primaryMembersRequired ? Cardinality.One : Cardinality.ZeroOrOne; } else { primaryRelationship.ThisCardinality = Cardinality.Many; } string primaryPropertyName = prefix + foreignName; if (!isOneToOne) { primaryPropertyName = Settings.RelationshipName(primaryPropertyName); } primaryPropertyName = ToPropertyName(primaryEntity.ClassName, primaryPropertyName); primaryPropertyName = _namer.UniqueName(primaryEntity.ClassName, primaryPropertyName); primaryRelationship.ThisPropertyName = primaryPropertyName; foreignRelationship.OtherPropertyName = primaryRelationship.ThisPropertyName; foreignRelationship.OtherCardinality = primaryRelationship.ThisCardinality; primaryRelationship.OtherPropertyName = foreignRelationship.ThisPropertyName; primaryRelationship.OtherCardinality = foreignRelationship.ThisCardinality; foreignRelationship.IsProcessed = true; primaryRelationship.IsProcessed = true; }
private static bool IsOneToOne(TableKeySchema tableKeySchema, Relationship foreignRelationship) { bool isFkeyPkey = tableKeySchema.ForeignKeyTable.HasPrimaryKey && tableKeySchema.ForeignKeyTable.PrimaryKey != null && tableKeySchema.ForeignKeyTable.PrimaryKey.MemberColumns.Count == 1 && tableKeySchema.ForeignKeyTable.PrimaryKey.MemberColumns.Contains( foreignRelationship.ThisProperties.FirstOrDefault()); if (isFkeyPkey) return true; // if f.key is unique return tableKeySchema.ForeignKeyMemberColumns.All(column => column.IsUnique); }
public TableKeySchema[] GetTableKeys(string connectionString, TableSchema table) { //0, 2, 3; catalog, table, key name DataTable dt = GetSchemaData(connectionString, ForeignKeys, null /*restrictions[0] - catalog*/, null /*restrictions[1] - unused*/, table.Name /*restrictions[2] - table*/, null /*restrictions[3] - key name*/); TableKeySchema[] keys = new TableKeySchema[dt.Rows.Count]; int keyIdx = 0; foreach (DataRow dr in dt.Rows) { TableKeySchema key = new TableKeySchema(table.Database, (String)dr[ForeignKeysNameColumn], new string[] { (String)dr[ForeignKeysFromColColumn] }, (String)dr[ForeignKeysFromTableColumn], new string[] { (String)dr[ForeignKeysToColColumn] }, (String)dr[ForeignKeysToTableColumn]); keys[keyIdx++] = key; } return keys; }
/* ///<summary> /// returns true all primary key columns have is a foreign key relationship /// </summary> public bool Many2ManyCompliant(TableKeySchema primaryKey) { // une seul column vers la table pivot if (primaryKey.ForeignKeyMemberColumns.Count != 1) return false; // une seul column venant de la table primaire if (primaryKey.PrimaryKeyMemberColumns.Count != 1) return false; // Junction table require a primary on two columns if (primaryKey.ForeignKeyTable.PrimaryKey == null || primaryKey.ForeignKeyTable.PrimaryKey.MemberColumns.Count != 2) { //Response.WriteLine(string.Format("IsJunctionTable: The table {0} doesn't have a primary key.", table.Name)); return false; } // And each primary key member columns must be part of relation for (int i=0;i < primaryKey.ForeignKeyTable.PrimaryKey.MemberColumns.Count; i++) { if (!primaryKey.ForeignKeyTable.PrimaryKey.MemberColumns[i].IsForeignKeyMember) return false; //if (!primaryKey.ForeignKeyTable.PrimaryKey.MemberColumns[i].IsPrimaryKeyMember) // return false; } // the foreign column of the relation must be a junction table's primary key member's column //if (primaryKey.ForeignKeyTable.PrimaryKey.MemberColumns[0] != primaryKey.ForeignKeyMemberColumns[0] && primaryKey.ForeignKeyTable.PrimaryKey.MemberColumns[1] != primaryKey.ForeignKeyMemberColumns[0]) //{ // return false; //} if (!primaryKey.ForeignKeyMemberColumns[0].IsPrimaryKeyMember) return false; return true; } */ /* public bool IsJunctionTable(TableSchema table) { bool RetValue; ColumnSchemaCollection keys; RetValue = false; if(table.PrimaryKey.MemberColumns.Count > 1) { keys = new ColumnSchemaCollection(SourceTable.PrimaryKey.MemberColumns); foreach(ColumnSchema primarykey in keys) { if(primarykey.IsForeignKeyMember) { RetValue = true; } else { RetValue = false; break; } } } return RetValue; } */ ///<summary> /// Returns whether or not a table key is a one to one /// relationship with another table. /// WARNING: Assumes first column is the FK. ///</summary> public bool IsRelationOneToOne(TableKeySchema keyschema) { foreach(IndexSchema i in keyschema.ForeignKeyTable.Indexes) { if((i.MemberColumns[0].Name == keyschema.ForeignKeyMemberColumns[0].Name) && (!IsJunctionTable(keyschema.ForeignKeyTable))) { if(i.IsUnique || i.IsPrimaryKey) { return true; } else { return false; } } } return false; }