예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
 public async void Error_On_Column_Counts_Not_Matching(string location1, string location2, string foreignKey)
 {
     await VerifyForeignKeyErrorRaised(ModelBuilderError.ForeignKeyColumnCountsDontMatch(), foreignKey, location1, location2);
 }