efcore / EFCore.FSharp

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

[Single case DUs] The binary operator Equal is not defined for the types `UserId` and `UserId` #139

Open xperiandri opened 2 years ago

xperiandri commented 2 years ago

Describe the bug Having such IdentityUser definition

type ApplicationUser () =
    inherit IdentityUser<KeyType> ()

    member _.Id
        with get() : UserId = base.Id |> UserId
        and set ((UserId value) : UserId) = base.Id <- value

    member val FirstName = Unchecked.defaultof<String option> with get, set
    member val LastName = Unchecked.defaultof<String option> with get, set

    [<NotMapped>]
    override this.NormalizedUserName
        with get () = this.UserName.ToUpper (CultureInfo.InvariantCulture)
        and set _ = ()

    [<NotMapped>]
    override this.NormalizedEmail
        with get () = this.Email.ToUpper (CultureInfo.InvariantCulture)
        and set _ = ()

and UserId = UserId of Guid

when I make UserId as and [<Struct>] UserId = UserId of Guid I get the error

The binary operator Equal is not defined for the types 'UserId' and 'UserId'

Expected behavior No error

Desktop (please complete the following information):

Smartphone (please complete the following information):

simon-reynolds commented 2 years ago

Hi @xperiandri It looks like the issue is from when trying to set the UserId type as your key type

To allow using it you need to implement IEquatable This may be what you need

[<Struct; CustomEquality; CustomComparison>]
type UserId = 
    | UserId of Guid
    interface IComparable with
        member x.CompareTo y =
            match y with
            | :? UserId as y ->
                match x, y with
                | UserId x', UserId y' -> x'.CompareTo y'
            | _ -> -1
    interface IEquatable<UserId> with
        member x.Equals(y) =
            match x, y with
            | UserId x', UserId y' -> x' = y'

Let me know if it works for you or if you had to make any other changes to get it working