efcore/EFCore.FSharp

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

Opened this issue · 1 comments

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):

  • OS: [e.g. iOS]
  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]

Smartphone (please complete the following information):

  • Version 6.0.6

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