/// <summary> /// Default constructor. /// </summary> public StatementSqlBuilderJoinInstruction( GenericStatementSqlBuilder sqlBuilder, SqlJoinType joinType, FormattableString whereClause, FormattableString orderClause) { this.SqlBuilder = sqlBuilder; this.JoinType = joinType; this.WhereClause = whereClause; this.OrderClause = orderClause; }
/// <summary> /// Default constructor. /// </summary> public StatementSqlBuilderJoinInstruction( GenericStatementSqlBuilder sqlBuilder, SqlJoinType joinType, FormattableString whereClause, FormattableString orderClause) { SqlBuilder = sqlBuilder; JoinType = joinType; WhereClause = whereClause; OrderClause = orderClause; }
private void FindRelationship( GenericStatementSqlBuilder firstEntitySqlBuilder, GenericStatementSqlBuilder secondEntitySqlBuilder, out PropertyMapping[] firstEntityRelationshipPropertyMappings, out PropertyMapping[] secondEntityRelationshipPropertyMappings, ref SqlJoinType secondEntityJoinType) { var firstEntityMapping = firstEntitySqlBuilder.EntityMapping; var secondEntityMapping = secondEntitySqlBuilder.EntityMapping; EntityMappingRelationship firstToSecondEntityMappingRelationship; EntityMappingRelationship secondToFirstEntityMappingRelationship; // two flags in order to cover 1-to-1 relationships bool firstToSecondParentChildRelationship; bool secondToFirstParentChildRelationship; this.FindRelationship(firstEntityMapping, secondEntityMapping, out firstToSecondEntityMappingRelationship, out firstToSecondParentChildRelationship); this.FindRelationship(secondEntityMapping, firstEntityMapping, out secondToFirstEntityMappingRelationship, out secondToFirstParentChildRelationship); if (firstToSecondEntityMappingRelationship == null && secondToFirstEntityMappingRelationship == null) { // no relationship was found on either side firstEntityRelationshipPropertyMappings = null; secondEntityRelationshipPropertyMappings = null; return; } firstEntityRelationshipPropertyMappings = firstToSecondEntityMappingRelationship?.ReferencingKeyProperties; secondEntityRelationshipPropertyMappings = secondToFirstEntityMappingRelationship?.ReferencingKeyProperties; // fix the lack of relationship info on one side, this is an acceptable scenario on parent entities only if (firstToSecondEntityMappingRelationship == null) { if (secondToFirstParentChildRelationship) { // first * - 1 second throw new InvalidOperationException($"Expected to find foreign keys on the '{firstEntityMapping.EntityType}' entity for the '{secondEntityMapping.EntityType}' entity"); } else { // first 1 - * second firstEntityRelationshipPropertyMappings = firstEntitySqlBuilder.KeyProperties; firstToSecondParentChildRelationship = true; } } else if (secondToFirstEntityMappingRelationship == null) { if (firstToSecondParentChildRelationship) { // second * - 1 first throw new InvalidOperationException($"Expected to find foreign keys on the '{secondEntityMapping.EntityType}' entity for the '{firstEntityMapping.EntityType}' entity"); } else { // second 1 - * second secondEntityRelationshipPropertyMappings = secondEntitySqlBuilder.KeyProperties; secondToFirstParentChildRelationship = true; } } if (firstEntityRelationshipPropertyMappings.Length != secondEntityRelationshipPropertyMappings.Length) { throw new InvalidOperationException($"Mismatch in the number of properties that are part of the relationship between '{firstEntityMapping.EntityType}' ({firstEntityRelationshipPropertyMappings.Length} properties) and '{secondEntityMapping.EntityType}' ({secondEntityRelationshipPropertyMappings.Length} properties)"); } // in case the second entity is a child, one of its foreign key properties is not nullable and the join type wasn't specified, default to INNER JOIN if (secondEntityJoinType == SqlJoinType.NotSpecified && secondToFirstParentChildRelationship == false && secondEntityRelationshipPropertyMappings.Any(propMapping => { var propType = propMapping.Descriptor.PropertyType; return (#if COREFX propType.GetTypeInfo().IsValueType #else propType.IsValueType #endif && Nullable.GetUnderlyingType(propMapping.Descriptor.PropertyType) == null); })) { secondEntityJoinType = SqlJoinType.InnerJoin; } }