9393 static Func<string, StoredProcedure, string> StoredProcedureReturnModelRename;
9494 Func<Column, Table, Column> UpdateColumn;
9595 Func<IList<ForeignKey>, Table, Table, bool, ForeignKey> ForeignKeyProcessing;
96+ Func<Table, Table, string, string[]> ForeignKeyAnnotationsProcessing;
9697 Func<ForeignKey, ForeignKey> ForeignKeyFilter;
9798 Func<string, ForeignKey, string, Relationship, short, string> ForeignKeyName;
9899 string MigrationConfigurationFileName = null;
638639 }
639640
640641 // Work out if there are any foreign key relationship naming clashes
641- reader.ProcessForeignKeys(fkList, tables, UsePascalCase, PrependSchemaName, CollectionType, true, IncludeComments, ForeignKeyName, UseDataAnnotationsSchema, ForeignKeyProcessing);
642+ reader.ProcessForeignKeys(fkList, tables, UsePascalCase, PrependSchemaName, CollectionType, true, IncludeComments, ForeignKeyName, UseDataAnnotationsSchema, ForeignKeyProcessing, ForeignKeyAnnotationsProcessing );
642643 if(UseMappingTables)
643- tables.IdentifyMappingTables(fkList, UsePascalCase, CollectionType, true, IncludeComments, IsSqlCe, ForeignKeyName);
644+ tables.IdentifyMappingTables(fkList, UsePascalCase, CollectionType, true, IncludeComments, IsSqlCe, ForeignKeyName, ForeignKeyAnnotationsProcessing );
644645
645646 // Now we know our foreign key relationships and have worked out if there are any name clashes,
646647 // re-map again with intelligently named relationships.
647648 tables.ResetNavigationProperties();
648649
649- reader.ProcessForeignKeys(fkList, tables, UsePascalCase, PrependSchemaName, CollectionType, false, IncludeComments, ForeignKeyName, UseDataAnnotationsSchema, ForeignKeyProcessing);
650+ reader.ProcessForeignKeys(fkList, tables, UsePascalCase, PrependSchemaName, CollectionType, false, IncludeComments, ForeignKeyName, UseDataAnnotationsSchema, ForeignKeyProcessing, ForeignKeyAnnotationsProcessing );
650651 if(UseMappingTables)
651- tables.IdentifyMappingTables(fkList, UsePascalCase, CollectionType, false, IncludeComments, IsSqlCe, ForeignKeyName);
652+ tables.IdentifyMappingTables(fkList, UsePascalCase, CollectionType, false, IncludeComments, IsSqlCe, ForeignKeyName, ForeignKeyAnnotationsProcessing );
652653
653654 conn.Close();
654655 return tables;
805806 {
806807 public string Definition;
807808 public string Comments;
809+ public string[] AdditionalDataAnnotations;
808810 }
809811
810812 public class Column
14991501 public abstract Tables ReadSchema(Regex schemaFilterExclude, Regex schemaFilterInclude, Regex tableFilterExclude, Regex tableFilterInclude, Regex columnFilterExclude, Func<Table, bool> tableFilter, bool usePascalCase, bool prependSchemaName, CommentsStyle includeComments, bool includeViews, CommentsStyle includeExtendedPropertyComments, Func<string, string, bool, string> tableRename, Func<Column, Table, Column> updateColumn, bool usePrivateSetterForComputedColumns, bool includeSynonyms, bool dataAnnotations, bool dataAnnotationsSchema, bool isSqlCe, Dictionary<string, string> columnNameToDataAnnotation, bool includeConnectionSettingComments);
15001502 public abstract List<StoredProcedure> ReadStoredProcs(Regex SchemaFilterExclude, Regex storedProcedureFilterExclude, bool usePascalCase, bool prependSchemaName , Func<StoredProcedure, string> StoredProcedureRename, bool includeTableValuedFunctions, bool includeConnectionSettingComments);
15011503 public abstract List<ForeignKey> ReadForeignKeys(Func<string, string, bool, string> tableRename, Func<ForeignKey, ForeignKey> foreignKeyFilter);
1502- public abstract void ProcessForeignKeys(List<ForeignKey> fkList, Tables tables, bool usePascalCase, bool prependSchemaName, string collectionType, bool checkForFkNameClashes, CommentsStyle includeComments, Func<string, ForeignKey, string, Relationship, short, string> ForeignKeyName, bool dataAnnotationsSchema, Func<IList<ForeignKey>, Table, Table, bool, ForeignKey> foreignKeyProcessing);
1504+ public abstract void ProcessForeignKeys(List<ForeignKey> fkList, Tables tables, bool usePascalCase, bool prependSchemaName, string collectionType, bool checkForFkNameClashes, CommentsStyle includeComments, Func<string, ForeignKey, string, Relationship, short, string> ForeignKeyName, bool dataAnnotationsSchema, Func<IList<ForeignKey>, Table, Table, bool, ForeignKey> foreignKeyProcessing, Func<Table, Table, string, string[]> foreignKeyAnnotationsProcessing );
15031505 public abstract void IdentifyForeignKeys(List<ForeignKey> fkList, Tables tables);
15041506 public abstract void ReadIndexes(Tables tables);
15051507 public abstract void ReadExtendedProperties(Tables tables, bool includeConnectionSettingComments);
@@ -2607,7 +2609,7 @@ SELECT SERVERPROPERTY('Edition') AS Edition,
26072609 }
26082610 }
26092611
2610- public override void ProcessForeignKeys(List<ForeignKey> fkList, Tables tables, bool usePascalCase, bool prependSchemaName, string collectionType, bool checkForFkNameClashes, CommentsStyle includeComments, Func<string, ForeignKey, string, Relationship, short, string> ForeignKeyName, bool dataAnnotationsSchema, Func<IList<ForeignKey>, Table, Table, bool, ForeignKey> foreignKeyProcessing)
2612+ public override void ProcessForeignKeys(List<ForeignKey> fkList, Tables tables, bool usePascalCase, bool prependSchemaName, string collectionType, bool checkForFkNameClashes, CommentsStyle includeComments, Func<string, ForeignKey, string, Relationship, short, string> ForeignKeyName, bool dataAnnotationsSchema, Func<IList<ForeignKey>, Table, Table, bool, ForeignKey> foreignKeyProcessing, Func<Table, Table, string, string[]> foreignKeyAnnotationsProcessing )
26112613 {
26122614 var constraints = fkList.Select(x => x.FkSchema + "." + x.ConstraintName).Distinct();
26132615 foreach (var constraint in constraints)
@@ -2670,6 +2672,7 @@ SELECT SERVERPROPERTY('Edition') AS Edition,
26702672 }
26712673
26722674 var fkd = new PropertyAndComments();
2675+ fkd.AdditionalDataAnnotations = foreignKeyAnnotationsProcessing != null ? foreignKeyAnnotationsProcessing(fkTable, pkTable, pkPropName) : null;
26732676 fkd.Definition = string.Format("{0}public {1}{2} {3} {4}{5}", dataAnnotation, Table.GetLazyLoadingMarker(), pkTableHumanCaseWithSuffix, pkPropName, "{ get; set; }", includeComments != CommentsStyle.None ? " // " + foreignKey.ConstraintName : string.Empty);
26742677 fkd.Comments = string.Format("Parent {0} pointed by [{1}].({2}) ({3})", pkTableHumanCase, fkTable.Name, string.Join(", ", fkCols.Select(x => "[" + x.col.NameHumanCase + "]").Distinct().ToArray()), foreignKey.ConstraintName);
26752678 fkCol.col.EntityFk.Add(fkd);
@@ -2691,7 +2694,7 @@ SELECT SERVERPROPERTY('Edition') AS Edition,
26912694 }
26922695
26932696 if(foreignKey.IncludeReverseNavigation)
2694- pkTable.AddReverseNavigation(relationship, pkTableHumanCase, fkTable, fkPropName, string.Format("{0}.{1}", fkTable.Name, foreignKey.ConstraintName), collectionType, includeComments, foreignKeys);
2697+ pkTable.AddReverseNavigation(relationship, pkTableHumanCase, fkTable, fkPropName, string.Format("{0}.{1}", fkTable.Name, foreignKey.ConstraintName), collectionType, includeComments, foreignKeys, foreignKeyAnnotationsProcessing );
26952698 }
26962699 }
26972700
@@ -3317,7 +3320,7 @@ SELECT SERVERPROPERTY('Edition') AS Edition,
33173320 return ForeignKeyName(tableNameHumanCase, foreignKey, fkName, relationship, 6);
33183321 }
33193322
3320- public void AddReverseNavigation(Relationship relationship, string fkName, Table fkTable, string propName, string constraint, string collectionType, CommentsStyle includeComments, List<ForeignKey> fks, Table mappingTable = null)
3323+ public void AddReverseNavigation(Relationship relationship, string fkName, Table fkTable, string propName, string constraint, string collectionType, CommentsStyle includeComments, List<ForeignKey> fks, Func<Table, Table, string, string[]> foreignKeyAnnotationsProcessing = null, Table mappingTable = null)
33213324 {
33223325 string fkNames = "";
33233326 switch (relationship)
@@ -3339,6 +3342,7 @@ SELECT SERVERPROPERTY('Edition') AS Edition,
33393342 ReverseNavigationProperty.Add(
33403343 new PropertyAndComments()
33413344 {
3345+ AdditionalDataAnnotations = foreignKeyAnnotationsProcessing != null ? foreignKeyAnnotationsProcessing(fkTable, this, propName) : null,
33423346 Definition = string.Format("public {0}{1} {2} {{ get; set; }}{3}", GetLazyLoadingMarker(), fkTable.NameHumanCaseWithSuffix, propName, includeComments != CommentsStyle.None ? " // " + constraint : string.Empty),
33433347 Comments = string.Format("Parent (One-to-One) {0} pointed by [{1}].{2} ({3})", this.NameHumanCaseWithSuffix, fkTable.Name, fkNames, fks.First().ConstraintName)
33443348 }
@@ -3349,6 +3353,7 @@ SELECT SERVERPROPERTY('Edition') AS Edition,
33493353 ReverseNavigationProperty.Add(
33503354 new PropertyAndComments()
33513355 {
3356+ AdditionalDataAnnotations = foreignKeyAnnotationsProcessing != null ? foreignKeyAnnotationsProcessing(fkTable, this, propName) : null,
33523357 Definition = string.Format("public {0}{1} {2} {{ get; set; }}{3}", GetLazyLoadingMarker(), fkTable.NameHumanCaseWithSuffix, propName, includeComments != CommentsStyle.None ? " // " + constraint : string.Empty),
33533358 Comments = string.Format("Parent {0} pointed by [{1}].{2} ({3})", NameHumanCaseWithSuffix, fkTable.Name, fkNames, fks.First().ConstraintName)
33543359 }
@@ -3362,6 +3367,7 @@ SELECT SERVERPROPERTY('Edition') AS Edition,
33623367 ReverseNavigationProperty.Add(
33633368 new PropertyAndComments()
33643369 {
3370+ AdditionalDataAnnotations = foreignKeyAnnotationsProcessing != null ? foreignKeyAnnotationsProcessing(fkTable, this, propName) : null,
33653371 Definition = string.Format("public {0}System.Collections.Generic.ICollection<{1}> {2} {{ get; set; }}{3}{4}", GetLazyLoadingMarker(), fkTable.NameHumanCaseWithSuffix, propName, initialization1, includeComments != CommentsStyle.None ? " // " + constraint : string.Empty),
33663372 Comments = string.Format("Child {0} where [{1}].{2} point to this entity ({3})", Inflector.MakePlural(fkTable.NameHumanCase), fkTable.Name, fkNames, fks.First().ConstraintName)
33673373 }
@@ -3376,6 +3382,7 @@ SELECT SERVERPROPERTY('Edition') AS Edition,
33763382 ReverseNavigationProperty.Add(
33773383 new PropertyAndComments()
33783384 {
3385+ AdditionalDataAnnotations = foreignKeyAnnotationsProcessing != null ? foreignKeyAnnotationsProcessing(fkTable, this, propName) : null,
33793386 Definition = string.Format("public {0}System.Collections.Generic.ICollection<{1}> {2} {{ get; set; }}{3}{4}", GetLazyLoadingMarker(), fkTable.NameHumanCaseWithSuffix, propName, initialization2, includeComments != CommentsStyle.None ? " // Many to many mapping" : string.Empty),
33803387 Comments = string.Format("Child {0} (Many-to-Many) mapped by table [{1}]", Inflector.MakePlural(fkTable.NameHumanCase), mappingTable == null ? string.Empty : mappingTable.Name)
33813388 }
@@ -3399,7 +3406,7 @@ SELECT SERVERPROPERTY('Edition') AS Edition,
33993406 }});", leftPropName, rightPropName, left.FkTableName, left.FkColumn, right.FkColumn, isSqlCe ? string.Empty : ", \"" + left.FkSchema + "\""));
34003407 }
34013408
3402- public void IdentifyMappingTable(List<ForeignKey> fkList, Tables tables, bool usePascalCase, string collectionType, bool checkForFkNameClashes, CommentsStyle includeComments, bool isSqlCe, Func<string, ForeignKey, string, Relationship, short, string> ForeignKeyName )
3409+ public void IdentifyMappingTable(List<ForeignKey> fkList, Tables tables, bool usePascalCase, string collectionType, bool checkForFkNameClashes, CommentsStyle includeComments, bool isSqlCe, Func<string, ForeignKey, string, Relationship, short, string> foreignKeyName, Func<Table, Table, string, string[]> foreignKeyAnnotationsProcessing )
34033410 {
34043411 IsMapping = false;
34053412
@@ -3440,13 +3447,13 @@ SELECT SERVERPROPERTY('Edition') AS Edition,
34403447 if (rightTable == null)
34413448 return;
34423449
3443- var leftPropName = leftTable.GetUniqueColumnName(rightTable.NameHumanCase, right, usePascalCase, checkForFkNameClashes, false, ForeignKeyName , Relationship.ManyToOne); // relationship from the mapping table to each side is Many-to-One
3444- var rightPropName = rightTable.GetUniqueColumnName(leftTable.NameHumanCase, left, usePascalCase, checkForFkNameClashes, false, ForeignKeyName , Relationship.ManyToOne); // relationship from the mapping table to each side is Many-to-One
3450+ var leftPropName = leftTable.GetUniqueColumnName(rightTable.NameHumanCase, right, usePascalCase, checkForFkNameClashes, false, foreignKeyName , Relationship.ManyToOne); // relationship from the mapping table to each side is Many-to-One
3451+ var rightPropName = rightTable.GetUniqueColumnName(leftTable.NameHumanCase, left, usePascalCase, checkForFkNameClashes, false, foreignKeyName , Relationship.ManyToOne); // relationship from the mapping table to each side is Many-to-One
34453452 leftTable.AddMappingConfiguration(left, right, usePascalCase, leftPropName, rightPropName, isSqlCe);
34463453
34473454 IsMapping = true;
3448- rightTable.AddReverseNavigation(Relationship.ManyToMany, rightTable.NameHumanCase, leftTable, rightPropName, null, collectionType, includeComments, null, mappingTable: this);
3449- leftTable .AddReverseNavigation(Relationship.ManyToMany, leftTable.NameHumanCase, rightTable, leftPropName, null, collectionType, includeComments, null, mappingTable: this);
3455+ rightTable.AddReverseNavigation(Relationship.ManyToMany, rightTable.NameHumanCase, leftTable, rightPropName, null, collectionType, includeComments, null, foreignKeyAnnotationsProcessing, this);
3456+ leftTable.AddReverseNavigation(Relationship.ManyToMany, leftTable.NameHumanCase, rightTable, leftPropName, null, collectionType, includeComments, null, foreignKeyAnnotationsProcessing, this);
34503457 }
34513458
34523459 public void SetupDataAnnotations()
@@ -3478,11 +3485,11 @@ SELECT SERVERPROPERTY('Edition') AS Edition,
34783485 }
34793486 }
34803487
3481- public void IdentifyMappingTables(List<ForeignKey> fkList, bool usePascalCase, string collectionType, bool checkForFkNameClashes, CommentsStyle includeComments, bool isSqlCe, Func<string, ForeignKey, string, Relationship, short, string> ForeignKeyName )
3488+ public void IdentifyMappingTables(List<ForeignKey> fkList, bool usePascalCase, string collectionType, bool checkForFkNameClashes, CommentsStyle includeComments, bool isSqlCe, Func<string, ForeignKey, string, Relationship, short, string> foreignKeyName, Func<Table, Table, string, string[]> foreignKeyAnnotationsProcessing )
34823489 {
34833490 foreach(var tbl in this.Where(x => x.HasForeignKey))
34843491 {
3485- tbl.IdentifyMappingTable(fkList, this, usePascalCase, collectionType, checkForFkNameClashes, includeComments, isSqlCe, ForeignKeyName );
3492+ tbl.IdentifyMappingTable(fkList, this, usePascalCase, collectionType, checkForFkNameClashes, includeComments, isSqlCe, foreignKeyName, foreignKeyAnnotationsProcessing );
34863493 }
34873494 }
34883495
0 commit comments