@@ -49,16 +49,17 @@ private static string GenerateCreateTableSqlQueries(List<NinjadogEntityWithKey>
4949 {
5050 stringBuilder
5151 . AppendLine ( )
52- . AppendLine ( $ "await connection.ExecuteAsync(@\" { GenerateSqlCreateTableQuery ( entity , enumNames , softDelete , auditing , provider ) } \" );") ;
52+ . AppendLine ( $ "await connection.ExecuteAsync(@\" { GenerateSqlCreateTableQuery ( entity , entities , enumNames , softDelete , auditing , provider ) } \" );") ;
5353 }
5454
5555 return stringBuilder . ToString ( ) ;
5656 }
5757
58- private static string GenerateSqlCreateTableQuery ( NinjadogEntityWithKey entity , HashSet < string > ? enumNames , bool softDelete , bool auditing , string provider )
58+ private static string GenerateSqlCreateTableQuery ( NinjadogEntityWithKey entity , List < NinjadogEntityWithKey > allEntities , HashSet < string > ? enumNames , bool softDelete , bool auditing , string provider )
5959 {
6060 var st = entity . StringTokens ;
6161 var entityKey = entity . Properties . GetEntityKey ( ) ;
62+ var fkConstraints = GetForeignKeyConstraints ( entity , allEntities ) ;
6263 IndentedStringBuilder stringBuilder = new ( 0 ) ;
6364
6465 stringBuilder
@@ -74,7 +75,7 @@ private static string GenerateSqlCreateTableQuery(NinjadogEntityWithKey entity,
7475 {
7576 var p = nonKeyProperties [ i ] ;
7677 var isLast = i == nonKeyProperties . Count - 1 ;
77- var needsComma = ! isLast || softDelete || auditing ;
78+ var needsComma = ! isLast || softDelete || auditing || fkConstraints . Count > 0 ;
7879
7980 if ( needsComma )
8081 {
@@ -88,7 +89,7 @@ private static string GenerateSqlCreateTableQuery(NinjadogEntityWithKey entity,
8889
8990 if ( softDelete )
9091 {
91- var needsComma = auditing ;
92+ var needsComma = auditing || fkConstraints . Count > 0 ;
9293 stringBuilder
9394 . AppendLine ( "IsDeleted INTEGER NOT NULL DEFAULT 0," )
9495 . Append ( needsComma ? "DeletedAt TEXT," : "DeletedAt TEXT)" ) ;
@@ -100,14 +101,77 @@ private static string GenerateSqlCreateTableQuery(NinjadogEntityWithKey entity,
100101
101102 if ( auditing )
102103 {
104+ var needsComma = fkConstraints . Count > 0 ;
103105 stringBuilder
104- . AppendLine ( "CreatedAt TEXT NOT NULL," )
105- . Append ( "UpdatedAt TEXT)" ) ;
106+ . AppendLine ( "CreatedAt TEXT NOT NULL," ) ;
107+ if ( needsComma )
108+ {
109+ stringBuilder . AppendLine ( "UpdatedAt TEXT," ) ;
110+ }
111+ else
112+ {
113+ stringBuilder . Append ( "UpdatedAt TEXT)" ) ;
114+ }
115+ }
116+
117+ for ( var i = 0 ; i < fkConstraints . Count ; i ++ )
118+ {
119+ var ( fkColumn , parentTable , parentPk ) = fkConstraints [ i ] ;
120+ var isLast = i == fkConstraints . Count - 1 ;
121+ var constraint = $ "FOREIGN KEY ({ fkColumn } ) REFERENCES { parentTable } ({ parentPk } )";
122+
123+ if ( isLast )
124+ {
125+ stringBuilder . Append ( $ "{ constraint } )") ;
126+ }
127+ else
128+ {
129+ stringBuilder . AppendLine ( $ "{ constraint } ,") ;
130+ }
106131 }
107132
108133 return stringBuilder . ToString ( ) ;
109134 }
110135
136+ private static List < ( string FkColumn , string ParentTable , string ParentPk ) > GetForeignKeyConstraints (
137+ NinjadogEntityWithKey entity , List < NinjadogEntityWithKey > allEntities )
138+ {
139+ var constraints = new List < ( string FkColumn , string ParentTable , string ParentPk ) > ( ) ;
140+
141+ foreach ( var potentialParent in allEntities )
142+ {
143+ if ( potentialParent . Relationships == null )
144+ {
145+ continue ;
146+ }
147+
148+ foreach ( var ( _, relationship ) in potentialParent . Relationships )
149+ {
150+ if ( relationship . RelatedEntity != entity . Key )
151+ {
152+ continue ;
153+ }
154+
155+ if ( relationship . RelationshipType is not ( NinjadogEntityRelationshipType . OneToMany or NinjadogEntityRelationshipType . OneToOne ) )
156+ {
157+ continue ;
158+ }
159+
160+ var parentPk = potentialParent . Properties . GetEntityKey ( ) ;
161+ var fkColumnName = parentPk . Key == "Id"
162+ ? $ "{ potentialParent . Key } Id"
163+ : parentPk . Key ;
164+
165+ if ( entity . Properties . ContainsKey ( fkColumnName ) )
166+ {
167+ constraints . Add ( ( fkColumnName , potentialParent . StringTokens . Models , parentPk . Key ) ) ;
168+ }
169+ }
170+ }
171+
172+ return constraints ;
173+ }
174+
111175 private static string MapToDbType ( string typeName , string provider , HashSet < string > ? enumNames = null )
112176 {
113177 return enumNames ? . Contains ( typeName ) == true
0 commit comments