Closed LiteracyFanatic closed 2 years ago
Found one more code pattern that is broken
b.HasKey("LCVendorID")
.HasName("LCVendor_PK")
.IsClustered(false) |> ignore
b.HasKey("LCVendorID")
.HasName("LCVendor_PK") |> ignore
SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("LCVendorID"), false) |> ignore
Hi @LiteracyFanatic
Thank you for reporting this. If at all possible, can you provide the definition of LCAccount
and any related entities needed to reproduce the issue?
Here is a minimal piece of code that reproduces the UseIdentityColumn
and Navigation
issues when running an initial migration. Unfortunately, I haven't been able to reproduce the IsClustered
issue in a clean project yet.
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 _Customer: Customer
member this.Id with get() = this._Id and set v = this._Id <- 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 _AccountId: int
[<DefaultValue>] val mutable private _Account: Account
[<DefaultValue>] val mutable private _Profile: Profile
member this.Id with get() = this._Id and set v = this._Id <- v
member this.AccountId with get() = this._AccountId and set v = this._AccountId <- v
member this.Account with get() = this._Account and set v = this._Account <- v
member this.Profile with get() = this._Profile and set v = this._Profile <- v
[<AllowNullLiteral>]
type Profile() =
[<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
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
Hi @LiteracyFanatic
This should be address in v6.0.3 just pushed to NuGet. Looks like the IsClustered
issue had the same root cause but let me know if you find any other issues
Thanks for looking at this. I can confirm that this fixed the IsClustered
and UseIdentityColumn
problems. It seems that there is still a problem when an entity has more than one navigation property though. I've added the navigation Address
to Customer
from my previous example.
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 _Customer: Customer
member this.Id with get() = this._Id and set v = this._Id <- 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 _AccountId: int
[<DefaultValue>] val mutable private _Account: Account
[<DefaultValue>] val mutable private _Profile: Profile
[<DefaultValue>] val mutable private _Address: Address
member this.Id with get() = this._Id and set v = this._Id <- v
member this.AccountId with get() = this._AccountId and set v = this._AccountId <- v
member this.Account with get() = this._Account and set v = this._Account <- v
member this.Profile with get() = this._Profile and set v = this._Profile <- v
member this.Address with get() = this._Address and set v = this._Address <- v
[<AllowNullLiteral>]
type Profile() =
[<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 Address() =
[<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
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
The generated code unidents for each call to Navigate
like follows
modelBuilder.Entity("Test.Domain+Customer", (fun b ->
b.Navigation("Address") |> ignore
b.Navigation("Profile") |> ignore
)) |> ignore
Instead it should only unindent for the last call inside the Entity
call.
Resolved as part of work done in #123 v6.0.4 pushed to NuGet
Thanks! I can confirm that calls to Navigation
are now indented correctly and the initial migration builds successfully.
It looks like #123 has introduced some other issues that appear in subsequent migrations, but everything mentioned in this issue has been addressed so I've opened #124.
Describe the bug In previous versions, migrations were generating code like this
but in
v6.0.2
it now generates the followingwhich fails to compile
Code using
Navigation
also fails to restore the indentation level correctlyTo Reproduce Steps to reproduce the behavior: Run a migration after updating to .NET 6.
Expected behavior Migrations should compile successfully.