/// <summary> /// 添加外键。 /// </summary> /// <typeparam name="TEntity">实体类。</typeparam> /// <typeparam name="TPrincipal">主键类。</typeparam> /// <param name="columns">字段。</param> /// <param name="principalColumns">主键列。</param> /// <param name="onUpdate">更新时候对应的操作。</param> /// <param name="onDelete">删除时候对应的操作。</param> /// <returns>返回迁移构建实例。</returns> public virtual OperationBuilder <AddForeignKeyOperation> AddForeignKey <TEntity, TPrincipal>( Expression <Func <TEntity, object> > columns, Expression <Func <TPrincipal, object> > principalColumns = null, ReferentialAction onUpdate = ReferentialAction.NoAction, ReferentialAction onDelete = ReferentialAction.NoAction) { Check.NotNull(columns, nameof(columns)); var operation = new AddForeignKeyOperation { Table = typeof(TEntity).GetTableName(), Columns = columns.GetPropertyNames(), PrincipalTable = typeof(TPrincipal).GetTableName(), OnUpdate = onUpdate, OnDelete = onDelete }; if (principalColumns == null) { operation.PrincipalColumns = operation.Columns; } else { operation.PrincipalColumns = principalColumns.GetPropertyNames(); } operation.Name = OperationHelper.GetName(NameType.ForeignKey, operation.Table, operation.Columns, operation.PrincipalTable); Operations.Add(operation); return(new OperationBuilder <AddForeignKeyOperation>(operation)); }
/// <summary> /// 添加外键。 /// </summary> /// <param name="table">当前外键所在得表格。</param> /// <param name="columns">字段列表。</param> /// <param name="principal">主键所在得表格。</param> /// <param name="principalColumns">主键字段列表。</param> /// <param name="onUpdate">更新时候对应的操作。</param> /// <param name="onDelete">删除时候对应的操作。</param> /// <returns>返回迁移构建实例。</returns> public virtual OperationBuilder <AddForeignKeyOperation> AddForeignKey( string table, string[] columns, string principal, string[] principalColumns = null, ReferentialAction onUpdate = ReferentialAction.NoAction, ReferentialAction onDelete = ReferentialAction.NoAction) { Check.NotNull(columns, nameof(columns)); var operation = new AddForeignKeyOperation { Table = table, Columns = columns, PrincipalTable = principal, OnUpdate = onUpdate, OnDelete = onDelete }; operation.PrincipalColumns = principalColumns ?? operation.Columns; operation.Name = OperationHelper.GetName(NameType.ForeignKey, operation.Table, operation.Columns, operation.PrincipalTable); Operations.Add(operation); return(new OperationBuilder <AddForeignKeyOperation>(operation)); }
public virtual OperationBuilder <AddForeignKeyOperation> AddForeignKey( [NotNull] string name, [NotNull] string table, [NotNull] string[] columns, [NotNull] string principalTable, [CanBeNull] string schema = null, [CanBeNull] string principalSchema = null, [CanBeNull] string[] principalColumns = null, ReferentialAction onUpdate = ReferentialAction.NoAction, ReferentialAction onDelete = ReferentialAction.NoAction) { Check.NotEmpty(name, nameof(name)); Check.NotEmpty(table, nameof(table)); Check.NotEmpty(columns, nameof(columns)); Check.NotEmpty(principalTable, nameof(principalTable)); var operation = new AddForeignKeyOperation { Schema = schema, Table = table, Name = name, Columns = columns, PrincipalSchema = principalSchema, PrincipalTable = principalTable, PrincipalColumns = principalColumns, OnUpdate = onUpdate, OnDelete = onDelete }; Operations.Add(operation); return(new OperationBuilder <AddForeignKeyOperation>(operation)); }
/// <summary> /// Initializes a new instance of the <see cref="DatabaseRelationalKey"/> class. /// </summary> /// <param name="childTableName">The child table name.</param> /// <param name="childKey">The child key.</param> /// <param name="parentTableName">The parent table name.</param> /// <param name="parentKey">The parent key.</param> /// <param name="deleteAction">The delete action.</param> /// <param name="updateAction">The update action.</param> /// <exception cref="ArgumentException"> /// <paramref name="updateAction"/> or <paramref name="deleteAction"/> will throw this exception if given an invalid enum value. /// Alternatively if the child key is not a foreign key this will also be thrown. /// Furthermore, if the parent key is not a unique or primary key, this will also be thrown. /// </exception> /// <exception cref="ArgumentNullException"><paramref name="parentTableName"/> or <paramref name="childTableName"/> or <paramref name="parentKey"/> or <paramref name="childKey"/> is <c>null</c></exception> public DatabaseRelationalKey(Identifier childTableName, IDatabaseKey childKey, Identifier parentTableName, IDatabaseKey parentKey, ReferentialAction deleteAction, ReferentialAction updateAction) { if (!deleteAction.IsValid()) { throw new ArgumentException($"The { nameof(ReferentialAction) } provided must be a valid enum.", nameof(deleteAction)); } if (!updateAction.IsValid()) { throw new ArgumentException($"The { nameof(ReferentialAction) } provided must be a valid enum.", nameof(updateAction)); } ChildTable = childTableName ?? throw new ArgumentNullException(nameof(childTableName)); ChildKey = childKey ?? throw new ArgumentNullException(nameof(childKey)); ParentTable = parentTableName ?? throw new ArgumentNullException(nameof(parentTableName)); ParentKey = parentKey ?? throw new ArgumentNullException(nameof(parentKey)); if (ChildKey.KeyType != DatabaseKeyType.Foreign) { throw new ArgumentException($"The child key must be a foreign key, instead given a key of type '{ childKey.KeyType }'.", nameof(childKey)); } if (ParentKey.KeyType != DatabaseKeyType.Primary && ParentKey.KeyType != DatabaseKeyType.Unique) { throw new ArgumentException($"The parent key must be a primary or unique key, instead given a key of type '{ parentKey.KeyType }'.", nameof(parentKey)); } DeleteAction = deleteAction; UpdateAction = updateAction; }
public virtual void ForeignKeyAction( ReferentialAction referentialAction, [NotNull] SqlBatchBuilder builder) { Check.NotNull(builder, nameof(builder)); switch (referentialAction) { case ReferentialAction.Restrict: builder.Append("RESTRICT"); break; case ReferentialAction.Cascade: builder.Append("CASCADE"); break; case ReferentialAction.SetNull: builder.Append("SET NULL"); break; case ReferentialAction.SetDefault: builder.Append("SET DEFAULT"); break; } }
public static void ChildKey_PropertyGet_EqualsCtorArg() { const string childTableName = "child_table"; const string parentTableName = "parent_table"; const ReferentialAction deleteAction = ReferentialAction.Cascade; Identifier keyName = "test_child_key"; var childKeyMock = new Mock <IDatabaseKey>(); childKeyMock.Setup(k => k.KeyType).Returns(DatabaseKeyType.Foreign); childKeyMock.Setup(k => k.Name).Returns(keyName); var childKey = childKeyMock.Object; var parentKeyMock = new Mock <IDatabaseKey>(); parentKeyMock.Setup(k => k.KeyType).Returns(DatabaseKeyType.Primary); var parentKey = parentKeyMock.Object; var relationalKey = new OracleRelationalKey(childTableName, childKey, parentTableName, parentKey, deleteAction); Assert.Multiple(() => { Assert.That(relationalKey.ChildKey.Name.UnwrapSome(), Is.EqualTo(keyName)); Assert.That(relationalKey.ChildKey, Is.EqualTo(childKey)); }); }
public virtual OperationBuilder <AddForeignKeyOperation> ForeignKey( [NotNull] string name, [NotNull] Expression <Func <TColumns, object> > columns, [NotNull] string referencedTable, [CanBeNull] string referencedSchema = null, [CanBeNull] string[] referencedColumns = null, ReferentialAction onUpdate = ReferentialAction.NoAction, ReferentialAction onDelete = ReferentialAction.NoAction) { Check.NotEmpty(name, nameof(name)); Check.NotNull(columns, nameof(columns)); Check.NotEmpty(referencedTable, nameof(referencedTable)); var operation = new AddForeignKeyOperation { Schema = Operation.Schema, Table = Operation.Name, Name = name, Columns = Map(columns), ReferencedSchema = referencedSchema, ReferencedTable = referencedTable, ReferencedColumns = referencedColumns, OnUpdate = onUpdate, OnDelete = onDelete }; Operation.ForeignKeys.Add(operation); return(new OperationBuilder <AddForeignKeyOperation>(operation)); }
public static void Action_PropertyGet_MatchesCtorArgument() { const ReferentialAction action = ReferentialAction.SetDefault; var onUpdateActionAttr = new OnUpdateActionAttribute(action); Assert.That(onUpdateActionAttr.Action, Is.EqualTo(action)); }
/// <summary> /// 添加外键操作的相关定义。 /// </summary> /// <param name="referentialAction">外键操作。</param> /// <param name="builder"><see cref="MigrationCommandListBuilder"/>实例。</param> protected virtual void ForeignKeyAction( ReferentialAction referentialAction, MigrationCommandListBuilder builder) { Check.NotNull(builder, nameof(builder)); switch (referentialAction) { case ReferentialAction.Restrict: builder.Append("RESTRICT"); break; case ReferentialAction.Cascade: builder.Append("CASCADE"); break; case ReferentialAction.SetNull: builder.Append("SET NULL"); break; case ReferentialAction.SetDefault: builder.Append("SET DEFAULT"); break; default: Debug.Assert( referentialAction == ReferentialAction.NoAction, "Unexpected value: " + referentialAction); break; } }
/// <summary> /// Configures a multiple-column (composite) foreign key on the table. /// </summary> /// <param name="name"> The foreign key constraint name. </param> /// <param name="columns"> The columns used for the foreign key. </param> /// <param name="principalTable"> The table to which the foreign key is constrained. </param> /// <param name="principalColumns"> The columns to which the foreign key column is constrained. </param> /// <param name="principalSchema"> The schema that contains the table to which the foreign key is constrained. </param> /// <param name="onUpdate"> The <see cref="ReferentialAction" /> to use for updates. </param> /// <param name="onDelete"> The <see cref="ReferentialAction" /> to use for deletes. </param> /// <returns> The same builder so that multiple calls can be chained. </returns> public virtual OperationBuilder <AddForeignKeyOperation> ForeignKey( string name, Expression <Func <TColumns, object> > columns, string principalTable, string[]?principalColumns, string?principalSchema = null, ReferentialAction onUpdate = ReferentialAction.NoAction, ReferentialAction onDelete = ReferentialAction.NoAction) { Check.NotEmpty(name, nameof(name)); Check.NotNull(columns, nameof(columns)); Check.NotEmpty(principalTable, nameof(principalTable)); var operation = new AddForeignKeyOperation { Schema = Operation.Schema, Table = Operation.Name, Name = name, Columns = Map(columns), PrincipalSchema = principalSchema, PrincipalTable = principalTable, PrincipalColumns = principalColumns, OnUpdate = onUpdate, OnDelete = onDelete }; Operation.ForeignKeys.Add(operation); return(new OperationBuilder <AddForeignKeyOperation>(operation)); }
/// <summary> /// 添加外键。 /// </summary> /// <typeparam name="TPrincipal">主键类。</typeparam> /// <param name="columns">字段。</param> /// <param name="principalColumns">主键列。</param> /// <param name="onUpdate">更新时候对应的操作。</param> /// <param name="onDelete">删除时候对应的操作。</param> /// <param name="action">添加扩展操作。</param> /// <returns>返回迁移构建实例。</returns> public virtual CreateTableBuilder <TEntity> ForeignKey <TPrincipal>( [NotNull] Expression <Func <TEntity, object> > columns, [NotNull] Expression <Func <TPrincipal, object> > principalColumns = null, ReferentialAction onUpdate = ReferentialAction.NoAction, ReferentialAction onDelete = ReferentialAction.NoAction, Action <OperationBuilder <AddForeignKeyOperation> > action = null) { Check.NotNull(columns, nameof(columns)); var operation = new AddForeignKeyOperation { Table = Operation.Table, Columns = columns.GetPropertyNames(), PrincipalTable = _model.GetTable(typeof(TPrincipal)), OnUpdate = onUpdate, OnDelete = onDelete }; if (principalColumns == null) { operation.PrincipalColumns = operation.Columns; } else { operation.PrincipalColumns = principalColumns.GetPropertyNames(); } operation.Name = OperationHelper.GetName(NameType.ForeignKey, operation.Table, operation.Columns, operation.PrincipalTable); Operation.ForeignKeys.Add(operation); action?.Invoke(new OperationBuilder <AddForeignKeyOperation>(operation)); return(this); }
public ForeignKey(string name, Expression <Func <TEntityBuilder, object> > column, string principalTable, string principalColumn, ReferentialAction onDeleteAction) { Name = name; Column = column; PrincipalTable = principalTable; PrincipalColumn = principalColumn; OnDeleteAction = onDeleteAction; }
public ForeignKeyConstraint(string table, string name, string column, string referencedTable, ReferentialAction onUpdate, ReferentialAction onDelete) : base(table, name) { this.column = column; this.referencedTable = referencedTable; this.onUpdate = onUpdate; this.onDelete = onDelete; }
public static void Ctor_GivenNullParentKey_ThrowsArgumentNullException() { const string childTableName = "child_table"; var childKey = Mock.Of <IDatabaseKey>(); const string parentTableName = "parent_table"; const ReferentialAction deleteAction = ReferentialAction.NoAction; Assert.That(() => new OracleRelationalKey(childTableName, childKey, parentTableName, null, deleteAction), Throws.ArgumentNullException); }
public static void Ctor_GivenInvalidDeleteAction_ThrowsArgumentException() { const string childTableName = "child_table"; var childKey = Mock.Of <IDatabaseKey>(); const string parentTableName = "parent_table"; var parentKey = Mock.Of <IDatabaseKey>(); const ReferentialAction deleteAction = (ReferentialAction)55; Assert.That(() => new OracleRelationalKey(childTableName, childKey, parentTableName, parentKey, deleteAction), Throws.ArgumentException); }
public static void Ctor_GivenNullChildTable_ThrowsArgumentNullException() { var childKey = Mock.Of <IDatabaseKey>(); const string parentTableName = "parent_table"; var parentKey = Mock.Of <IDatabaseKey>(); const ReferentialAction deleteAction = ReferentialAction.NoAction; const ReferentialAction updateAction = ReferentialAction.NoAction; Assert.That(() => new MySqlRelationalKey(null, childKey, parentTableName, parentKey, deleteAction, updateAction), Throws.ArgumentNullException); }
public OnDeleteActionAttribute(ReferentialAction action) : base(new[] { Dialect.All }) { if (!action.IsValid()) { throw new ArgumentException($"The { nameof(ReferentialAction) } provided must be a valid enum.", nameof(action)); } Action = action; }
public OnDeleteActionAttribute(ReferentialAction action, params Type[] dialects) : base(dialects) { if (!action.IsValid()) { throw new ArgumentException($"The { nameof(ReferentialAction) } provided must be a valid enum.", nameof(action)); } Action = action; }
public static void Ctor_GivenSetDefaultDeleteAction_ThrowsArgumentException() { const string childTableName = "child_table"; const string parentTableName = "parent_table"; var childKey = Mock.Of <IDatabaseKey>(); var parentKey = Mock.Of <IDatabaseKey>(); const ReferentialAction deleteAction = ReferentialAction.SetDefault; const ReferentialAction updateAction = ReferentialAction.NoAction; Assert.That(() => new MySqlRelationalKey(childTableName, childKey, parentTableName, parentKey, deleteAction, updateAction), Throws.ArgumentException); }
protected override void ForeignKeyAction(ReferentialAction referentialAction, MigrationCommandListBuilder builder) { if (referentialAction == ReferentialAction.Restrict) { builder.Append("NO ACTION"); } else { base.ForeignKeyAction(referentialAction, builder); } }
public override void ForeignKeyAction(ReferentialAction referentialAction, SqlBatchBuilder builder) { Check.NotNull(builder, nameof(builder)); if (referentialAction == ReferentialAction.Restrict) { builder.Append("NO ACTION"); } else { base.ForeignKeyAction(referentialAction, builder); } }
protected override void ForeignKeyAction(ReferentialAction referentialAction, MigrationCommandListBuilder builder) { Check.NotNull(builder, nameof(builder)); if (referentialAction == ReferentialAction.Restrict) { builder.Append("RESTRICT"); } else { base.ForeignKeyAction(referentialAction, builder); } }
protected override void ForeignKeyAction(ReferentialAction referentialAction, MigrationCommandListBuilder builder) { switch (referentialAction) { case ReferentialAction.NoAction: builder.Append("NO ACTION"); break; default: base.ForeignKeyAction(referentialAction, builder); break; } }
public static void AddForeignKeySqlite( [NotNull] this MigrationBuilder builder, [NotNull] string name, [NotNull] string table, [NotNull] string column, [NotNull] string principalTable, string schema = null, string principalSchema = null, string principalColumn = null, ReferentialAction onUpdate = ReferentialAction.NoAction, ReferentialAction onDelete = ReferentialAction.NoAction) { // TODO(jpg): add foreign key }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public ForeignKeyConstraint( [NotNull] string name, [NotNull] Table table, [NotNull] Table principalTable, [NotNull] IReadOnlyList <Column> columns, [NotNull] IReadOnlyList <Column> principalColumns, ReferentialAction onDeleteAction) { Name = name; Table = table; PrincipalTable = principalTable; Columns = columns; PrincipalColumns = principalColumns; OnDeleteAction = onDeleteAction; }
public static void Ctor_GivenParentKeyNotCandidateKey_ThrowsArgumentException() { const string childTableName = "child_table"; const string parentTableName = "parent_table"; var childKeyMock = new Mock <IDatabaseKey>(); childKeyMock.Setup(k => k.KeyType).Returns(DatabaseKeyType.Foreign); var parentKeyMock = new Mock <IDatabaseKey>(); parentKeyMock.Setup(k => k.KeyType).Returns(DatabaseKeyType.Foreign); const ReferentialAction deleteAction = ReferentialAction.NoAction; Assert.That(() => new OracleRelationalKey(childTableName, childKeyMock.Object, parentTableName, parentKeyMock.Object, deleteAction), Throws.ArgumentException); }
/// <summary> /// Configures a single-column foreign key on the table. /// </summary> /// <param name="name"> The foreign key constraint name. </param> /// <param name="column"> The column used for the foreign key. </param> /// <param name="principalTable"> The table to which the foreign key is constrained. </param> /// <param name="principalColumn"> The column to which the foreign key column is constrained. </param> /// <param name="principalSchema"> The schema that contains the table to which the foreign key is constrained. </param> /// <param name="onUpdate"> The <see cref="ReferentialAction" /> to use for updates. </param> /// <param name="onDelete"> The <see cref="ReferentialAction" /> to use for deletes. </param> /// <returns> The same builder so that multiple calls can be chained. </returns> public virtual OperationBuilder <AddForeignKeyOperation> ForeignKey( string name, Expression <Func <TColumns, object> > column, string principalTable, string?principalColumn = null, string?principalSchema = null, ReferentialAction onUpdate = ReferentialAction.NoAction, ReferentialAction onDelete = ReferentialAction.NoAction) => ForeignKey( name, column, principalTable, principalColumn == null ? null : new[] { principalColumn }, principalSchema, onUpdate, onDelete);
public virtual OperationBuilder <AddForeignKeyOperation> ForeignKey( [NotNull] string name, [NotNull] Expression <Func <TColumns, object> > columns, [NotNull] string referencedTable, [NotNull] string referencedColumn, [CanBeNull] string referencedSchema = null, ReferentialAction onUpdate = ReferentialAction.NoAction, ReferentialAction onDelete = ReferentialAction.NoAction) => ForeignKey( name, columns, referencedTable, referencedSchema, new[] { referencedColumn }, onUpdate, onDelete);
public ForeignKey( string constraintName, IEnumerable <string> columnNames, Identifier parentTableName, string parentConstraintName, IEnumerable <string> parentColumnNames, ReferentialAction deleteAction, ReferentialAction updateAction, string rootPath ) : base(constraintName) { if (columnNames == null || columnNames.Empty()) { throw new ArgumentNullException(nameof(columnNames)); } if (parentTableName == null) { throw new ArgumentNullException(nameof(parentTableName)); } if (parentColumnNames == null || parentColumnNames.Empty()) { throw new ArgumentNullException(nameof(parentColumnNames)); } if (!deleteAction.IsValid()) { throw new ArgumentException($"The { nameof(ReferentialAction) } provided must be a valid enum.", nameof(deleteAction)); } if (!updateAction.IsValid()) { throw new ArgumentException($"The { nameof(ReferentialAction) } provided must be a valid enum.", nameof(updateAction)); } if (rootPath == null) { throw new ArgumentNullException(nameof(rootPath)); } ChildColumnNames = columnNames.Join(", "); ParentConstraintName = parentConstraintName; ParentTableName = parentTableName.ToVisibleName(); ParentTableUrl = rootPath + UrlRouter.GetTableUrl(parentTableName); ParentColumnNames = parentColumnNames.Join(", "); DeleteActionDescription = _actionDescription[deleteAction]; UpdateActionDescription = _actionDescription[updateAction]; }
public virtual OperationBuilder <AddForeignKeyOperation> AddForeignKey( [NotNull] string name, [NotNull] string table, [NotNull] string column, [NotNull] string principalTable, [CanBeNull] string schema = null, [CanBeNull] string principalSchema = null, [CanBeNull] string principalColumn = null, ReferentialAction onUpdate = ReferentialAction.NoAction, ReferentialAction onDelete = ReferentialAction.NoAction) => AddForeignKey( name, table, new[] { column }, principalTable, schema, principalSchema, new[] { principalColumn }, onUpdate, onDelete);
protected override void ForeignKeyAction(ReferentialAction referentialAction, MigrationCommandListBuilder builder) { Check.NotNull(builder, nameof(builder)); if (referentialAction == ReferentialAction.Restrict) { builder.Append("NO ACTION"); } else { base.ForeignKeyAction(referentialAction, builder); } }
protected virtual void ForeignKeyAction( ReferentialAction referentialAction, [NotNull] RelationalCommandListBuilder builder) { Check.NotNull(builder, nameof(builder)); switch (referentialAction) { case ReferentialAction.Restrict: builder.Append("RESTRICT"); break; case ReferentialAction.Cascade: builder.Append("CASCADE"); break; case ReferentialAction.SetNull: builder.Append("SET NULL"); break; case ReferentialAction.SetDefault: builder.Append("SET DEFAULT"); break; default: Debug.Assert( referentialAction == ReferentialAction.NoAction, "Unexpected value: " + referentialAction); break; } }