public static IForeignKey <TDatabase, TTable> ForeignKey <TDatabase, TTable, TReference>(this IForeignKeyBuilder <TDatabase, TTable> @this, Expression <Func <TTable, object> > keyColumns, Expression <Func <TDatabase, IEnumerable <TReference> > > referenceTable, Expression <Func <TReference, object> > referenceColumns, ForeignKeyAction updateAction = ForeignKeyAction.Cascade, ForeignKeyAction deleteAction = ForeignKeyAction.Cascade, string name = null) { var builder = @this as InternalTableBuilder <TDatabase, TTable>; var tempKeyColumns = ExpressionHelpers.ParseMultiPropertySelector(keyColumns ?? throw ModelBuilderError.ArgumentNull(nameof(keyColumns)).AsException()).MatchColumns(builder.Name, builder.Columns); var tempReferenceTable = ExpressionHelpers.ParseSelector(referenceTable ?? throw ModelBuilderError.ArgumentNull(nameof(referenceTable)).AsException()); var tempReferenceColumns = ExpressionHelpers.ParseMultiPropertySelector(referenceColumns ?? throw ModelBuilderError.ArgumentNull(nameof(referenceColumns)).AsException()); if (tempKeyColumns.Length != tempReferenceColumns.Length) { throw ModelBuilderError.ForeignKeyColumnCountsDontMatch().AsException(); } builder.ForeignKeys.Add(new ForeignKeyModel(name: name, keyColumns: tempKeyColumns.ToImmutableArray(), referenceTable: tempReferenceTable, referenceColumns: tempReferenceColumns.ToImmutableArray(), updateAction: updateAction, deleteAction: deleteAction)); return(builder); }
static FuzzyTableModel ParseTableForeignKey(SyntaxNodeAnalysisContext context, InvocationExpressionSyntax expression, FuzzyDatabaseModel partialDatabase) { var innerModel = ParseTableChain(context, expression, partialDatabase); var arguments = AH.ParseArguments(context, expression); var keyColumnsArg = arguments["keyColumns"]; var referenceTableArg = arguments["referenceTable"]; var referenceColumnsArg = arguments["referenceColumns"]; var updateActionArg = arguments["updateAction"]; var deleteActionArg = arguments["deleteAction"]; var nameArg = arguments["name"]; var fuzzyForeignKey = new FuzzyForeignKeyModel(); if (AH.IsNull(context, keyColumnsArg)) { context.ReportDiagnostic(BuilderError.ArgumentNull("keyColumns").MakeDiagnostic(keyColumnsArg.Expression.GetLocation())); fuzzyForeignKey.KeyColumns = new Optional <ImmutableArray <(FuzzyColumnModel, Location)> >(); } else { var keyColumns = AH.ParseMultiProperty(context, keyColumnsArg); if (keyColumns.HasValue) { fuzzyForeignKey.KeyColumns = AH.MatchColumns(context, keyColumns.Value, innerModel.Columns, ToString(innerModel.Name)); } } if (AH.IsNull(context, referenceTableArg)) { context.ReportDiagnostic(BuilderError.ArgumentNull("referenceTable").MakeDiagnostic(referenceTableArg.Expression.GetLocation())); fuzzyForeignKey.ReferenceTableSelector = new Optional <(FuzzyProperty, Location)>(); } else { var selector = AH.ParseSelector(context, referenceTableArg); fuzzyForeignKey.ReferenceTableSelector = selector.HasValue ? AH.Just((selector.Value, (referenceTableArg.Expression as LambdaExpressionSyntax).Body.GetLocation())) : new Optional <(FuzzyProperty, Location)>(); } if (AH.IsNull(context, referenceColumnsArg)) { context.ReportDiagnostic(BuilderError.ArgumentNull("referenceColumns").MakeDiagnostic(referenceColumnsArg.Expression.GetLocation())); fuzzyForeignKey.ReferenceColumnSelectors = new Optional <ImmutableArray <(FuzzyProperty, Location)> >(); } else { fuzzyForeignKey.ReferenceColumnSelectors = AH.ParseMultiProperty(context, referenceColumnsArg); } if (fuzzyForeignKey.KeyColumns.HasValue && fuzzyForeignKey.ReferenceColumnSelectors.HasValue && fuzzyForeignKey.KeyColumns.Value.Length != fuzzyForeignKey.ReferenceColumnSelectors.Value.Length) { context.ReportDiagnostic(ModelBuilderError.ForeignKeyColumnCountsDontMatch().MakeDiagnostic(AH.DeconstructLambda(keyColumnsArg).Body.GetLocation(), new List <Location>() { AH.DeconstructLambda(referenceColumnsArg).Body.GetLocation() })); } fuzzyForeignKey.UpdateAction = AH.ParseConstantArgument(context, updateActionArg, () => AH.Just(ForeignKeyAction.Cascade)); fuzzyForeignKey.DeleteAction = AH.ParseConstantArgument(context, deleteActionArg, () => AH.Just(ForeignKeyAction.Cascade)); innerModel.ForeignKeys.Add(fuzzyForeignKey); return(innerModel); }
public async void Error_On_Column_Counts_Not_Matching(string location1, string location2, string foreignKey) { await VerifyForeignKeyErrorRaised(ModelBuilderError.ForeignKeyColumnCountsDontMatch(), foreignKey, location1, location2); }