efcore / EFCore.FSharp

Adds F# design-time support to EF Core
MIT License
228 stars 26 forks source link

Missing calls to ignore in migrations #124

Closed LiteracyFanatic closed 2 years ago

LiteracyFanatic commented 2 years ago

Describe the bug Migrations fail to compile after #123 because of missing calls to ignore for some instances of AlterColumn. This is merely a warning most of the time, but causes an error when the last expression changes the return type of Up or Down.

        migrationBuilder.AlterColumn<int>(
            name = "Id"
            ,table = "Accounts"
            ,``type`` = "\"int\""
            ,nullable = false
            ,oldClrType = typedefof<int>
            ,oldType = "\"int\""
            ,oldNullable = false
            ,oldDefaultValue = "0"
            ).Annotation("SqlServer:Identity", "1, 1")
            .OldAnnotation("SqlServer:Identity", "1, 1")

Additional issues which don't result in a compilation error:

To Reproduce

  1. Generate an initial migration with the model below (note that this is altered slightly from the example used in #121 to remove ambiguity related to the owners of foreign keys).
namespace Test

open System
open System.Collections.Generic
open Microsoft.EntityFrameworkCore
open Microsoft.EntityFrameworkCore.Design
open Microsoft.EntityFrameworkCore.Metadata
open Microsoft.EntityFrameworkCore.Metadata.Builders
open EntityFrameworkCore.FSharp.Extensions

module rec Domain =
    [<AllowNullLiteral>]
    type Account() =
        [<DefaultValue>] val mutable private _Id: int
        [<DefaultValue>] val mutable private _CustomerId: int
        [<DefaultValue>] val mutable private _Customer: Customer
        member this.Id with get() = this._Id and set v = this._Id <- v
        member this.CustomerId with get() = this._CustomerId and set v = this._CustomerId <- v
        member this.Customer with get() = this._Customer and set v = this._Customer <- v

    [<AllowNullLiteral>]
    type Customer() =
        [<DefaultValue>] val mutable private _Id: int
        [<DefaultValue>] val mutable private _ProfileId: int
        [<DefaultValue>] val mutable private _Profile: Profile
        [<DefaultValue>] val mutable private _AddressId: int
        [<DefaultValue>] val mutable private _Address: Address
        member this.Id with get() = this._Id and set v = this._Id <- v
        member this.ProfileId with get() = this._ProfileId and set v = this._ProfileId <- v
        member this.Profile with get() = this._Profile and set v = this._Profile <- v
        member this.AddressId with get() = this._AddressId and set v = this._AddressId <- v
        member this.Address with get() = this._Address and set v = this._Address <- v

    [<AllowNullLiteral>]
    type Profile() =
        [<DefaultValue>] val mutable private _Id: int
        member this.Id with get() = this._Id and set v = this._Id <- v

    [<AllowNullLiteral>]
    type Address() =
        [<DefaultValue>] val mutable private _Id: int
        member this.Id with get() = this._Id and set v = this._Id <- v

    type LetsConnectContext() =
        inherit DbContext()

        [<DefaultValue>] val mutable private _Accounts : DbSet<Account>
        member this.Accounts with get() = this._Accounts and set v = this._Accounts <- v

        [<DefaultValue>] val mutable private _Customers : DbSet<Customer>
        member this.Customers with get() = this._Customers and set v = this._Customers <- v

        [<DefaultValue>] val mutable private _Profiles : DbSet<Profile>
        member this.Profiles with get() = this._Profiles and set v = this._Profiles <- v

        override _.OnModelCreating builder =
            builder.RegisterOptionTypes() // enables option values for all entities

        override __.OnConfiguring(options: DbContextOptionsBuilder) : unit =
            options.UseSqlServer(Environment.GetEnvironmentVariable("CONNECTION_STRING")) |> ignore
  1. Generate another migration without making any changes.
  2. Attempting to build the project results in the following errors.
/home/jordan/src/repro/Migrations/20211129223429_Change.fs(18,9): warning FS0020: The result of this expression has type 'Operations.Builders.AlterOperationBuilder<Operations.AlterColumnOperation>' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'. [/home/jordan/src/repro/repro.fsproj]
/home/jordan/src/repro/Migrations/20211129223429_Change.fs(53,9): warning FS0020: The result of this expression has type 'Operations.Builders.AlterOperationBuilder<Operations.AlterColumnOperation>' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'. [/home/jordan/src/repro/repro.fsproj]
/home/jordan/src/repro/Migrations/20211129223429_Change.fs(66,9): warning FS0020: The result of this expression has type 'Operations.Builders.AlterOperationBuilder<Operations.AlterColumnOperation>' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'. [/home/jordan/src/repro/repro.fsproj]
/home/jordan/src/repro/Migrations/20211129223429_Change.fs(105,9): warning FS0020: The result of this expression has type 'Operations.Builders.AlterOperationBuilder<Operations.AlterColumnOperation>' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'. [/home/jordan/src/repro/repro.fsproj]
/home/jordan/src/repro/Migrations/20211129223429_Change.fs(140,9): warning FS0020: The result of this expression has type 'Operations.Builders.AlterOperationBuilder<Operations.AlterColumnOperation>' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'. [/home/jordan/src/repro/repro.fsproj]
/home/jordan/src/repro/Migrations/20211129223429_Change.fs(153,9): warning FS0020: The result of this expression has type 'Operations.Builders.AlterOperationBuilder<Operations.AlterColumnOperation>' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'. [/home/jordan/src/repro/repro.fsproj]
/home/jordan/src/repro/Migrations/20211129223429_Change.fs(90,9): error FS0193: Type constraint mismatch. The type     'Operations.Builders.AlterOperationBuilder<Operations.AlterColumnOperation>'    is not compatible with type    'unit' [/home/jordan/src/repro/repro.fsproj]
/home/jordan/src/repro/Migrations/20211129223429_Change.fs(177,9): error FS0193: Type constraint mismatch. The type     'Operations.Builders.AlterOperationBuilder<Operations.AlterColumnOperation>'    is not compatible with type    'unit' [/home/jordan/src/repro/repro.fsproj]
    6 Warning(s)
    2 Error(s)
simon-reynolds commented 2 years ago

Hi @LiteracyFanatic Publishing v6.0.5 now which takes care of the code generation so that AlterColumn operations don't produce warnings any more

The AlterColumn operations shouldn't be generated at all, but I'll track that under #126

LiteracyFanatic commented 2 years ago

Confirming that test case builds without error now. Thanks a bunch.