Entity Framework Core: применить преобразование ко всем свойствам типа Option <T>в F # - PullRequest
0 голосов
/ 28 сентября 2018

Я использую Entity Framework Core 2.1 в F #.
Я хочу настроить общее преобразование типов для Option типов, чтобы EF знал, как с ними обращаться.

Я нашел этот очень полезный пост, который показывает, как настроить универсальный конвертер для Option типов.
Итак, вот что у меня есть (объединение фрагментов)

[<Table("Users", Schema = "pm")>]
type [<CLIMutable>] User = {
  [<DatabaseGenerated(DatabaseGeneratedOption.Identity)>]
  UserID           : int64
  FirstName        : string
  LastName         : string
  LastLoggedInTime : DateTimeOffset option
}
with
  static member Configure (mb : ModelBuilder) =
    mb.Entity<User>()
      .Property(fun p -> p.LastLoggedInTime)
      .HasConversion(OptionConverter<DateTimeOffset>()) |> ignore

Это замечательно, если только я не добавлю новое свойство к своему типу.Мне нужно будет добавить последние три строки приведенного выше кода для этого свойства.Я ищу способ сделать это для всех свойств одновременно: D

Итак, я нашел этот полезный ТАК ответ, который привел меня к приведенному ниже коду

let tt = mb.Model.GetEntityTypes()
         |> Seq.map(fun et -> et.GetProperties()) |> Seq.concat
         |> Seq.filter(fun p -> p.ClrType = typeof<Option<DateTimeOffset>>)
         |> Seq.map(fun p -> mb.Entity(p.DeclaringEntityType.ClrType)
                               .Property(p.Name)
                               .HasConversion(OptionConverter<DateTimeOffset>()))

Теперь проблема, которую я пытаюсь решить, состоит в том, чтобы выяснить, как заставить этот код работать с универсальными типами, чтобы мне не приходилось указывать тип.Я хочу, чтобы это было что-то вроде p.ClrType = typeof<Option<T'>> и в конце, что-то вроде .HasConversion(OptionConverter<T'>())

Есть мысли?

1 Ответ

0 голосов
/ 28 сентября 2018

Итак, отвечая на ваш первоначальный вопрос: «Я хочу настроить общее преобразование типов для типов Option, чтобы EF знал, как с ними обращаться».Я предполагаю, что вы имеете в виду, что вы хотите, чтобы EF правильно отобразил опцию в столбец «NULL» соответствующего базового типа, и что у вас возникают проблемы, потому что EF не знает, как обрабатывать FSharp.Option?

Вместо этого вы могли бы просто использовать Nullable вместо Option для ваших типов EF, и он разрешится так же, как и в C #.

Так, например, ваш пример типа становится:

type [<CLIMutable>] User = {
  [<DatabaseGenerated(DatabaseGeneratedOption.Identity)>]
  UserID           : int64
  FirstName        : string
  LastName         : string
  LastLoggedInTime : Nullable<DateTimeOffset>
}

Длятипы, которые не могут иметь значение Nullable, но являются опциями в вашем домене (например, строки), вы просто устанавливаете их в качестве базового типа, и он будет отлично работать.

Если вы сопоставляете типы доменов F # где-то еще,вы можете просто использовать Option.ToNullable и Option.OfNullable там, или сопоставить None со значением NULL, если тип не может быть обнуляем, как указано выше.

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...