项目作者: sulmar

项目描述 :
Przykład konwertera EF Core 2.1
高级语言: C#
项目地址: git://github.com/sulmar/EFCoreJsonConvert.git
创建时间: 2018-09-25T19:56:10Z
项目社区:https://github.com/sulmar/EFCoreJsonConvert

开源协议:

下载


Przykład konwertera EF Core 2.1

Wstęp

Czasami sposób zapisu wartości jakiejś właściwości w bazie danych różni się od tej zdefiniowanej w klasie.
Na przykład w modelu posiadamy np. płeć jako enum a w bazie danych chcemy zapisać jako “M” lub “F”.
Albo bardziej złożony przykład - po stronie modelu posiadamy obiekt z adresem lub parametrami urządzenia, a w bazie danych chcemy zapisać go w jednej kolumnie jako xml lub json.

Niestety w poprzedniej wersji EF 6 nie było gotowego mechanizmu i trzeba było stosować obejścia.
Najczęściej obejście polegało na tym, że trzeba było utworzyć w klasie dodatkowe ukryte prywatne pole (tzw. backfield) odpowiadające typowi w bazie danych, a docelowa właściwość była oznaczona jako ignorowana przez EF. Następnie w metodach get i set była realizowana konwersja. Nie było to optymalne rozwiązanie i kod nie był przenośny.

W EF Core wprowadzono nową funkcję, tzw. konwertery (ValueConverters), które rozwiązują ten problem w bardzo elegancki sposób.
Nie trzeba już tworzyć dodatkowych pól, ale przede wszystkim można wielokrotnie używać tej samej konwersji.
Konwerter można użyć w konfiguracji oraz w konwencji.

Konwersja za pomocą wyrażeń lambda

  1. builder.Property(p=>p.Gender)
  2. .HasConversion(
  3. v => v.ToString(),
  4. v => (Gender)Enum.Parse(typeof(Gender), v)
  5. );

Konwersja za pomocą obiektu konwertera

  1. var converter = new ValueConverter<Gender, string>(
  2. v => v.ToString(),
  3. v => (Gender)Enum.Parse(typeof(Gender), v));

Użycie wbudowanego konwertera

  1. var converter = new EnumToStringConverter<Gender>();
  2. builder.Property(p=>p.Gender)
  3. .HasConversion(converter);

Niektóre z konwerterów posiadają dodatkowe parametry:

  1. builder.Property(p=>p.IsDeleted)
  2. .HasConversion(new BoolToStringConverter("Y", "N"));

Lista wbudowanych konwerterów [https://docs.microsoft.com/en-us/ef/core/modeling/value-conversions]

Predefiniowane konwersje

W większości przypadków nie trzeba tworzyć konwerterów, bo wystarczy skorzystać z predefiniowanych konwersji:

  1. builder.Property(p=>p.Gender)
  2. .HasConversion<string>();

Własny konwerter

Własny konwerter za pomocą wyrażenia lambda

  1. builder.Property(p => p.ShippingAddress).HasConversion(
  2. v => JsonConvert.SerializeObject(v),
  3. v => JsonConvert.DeserializeObject<Address>(v));

Utworzenie własnego konwertera

Utworzenie klasy własnego konwertera

  1. public class JsonValueConverter<T> : ValueConverter<T, string>
  2. {
  3. public JsonValueConverter(ConverterMappingHints mappingHints = null)
  4. : base(v => JsonConvert.SerializeObject(v),
  5. v => JsonConvert.DeserializeObject<T>(v),
  6. mappingHints)
  7. {
  8. }
  9. }

Użycie własnego konwertera

  1. builder.Property(p => p.ShippingAddress).HasConversion(new JsonValueConverter<Address>());

W celu ułatwienia korzystania z konwertera można utworzyć metodę rozszerzającą

  1. public static class PropertyBuilderExtensions
  2. {
  3. public static PropertyBuilder<T> HasJsonValueConversion<T>(this PropertyBuilder<T> propertyBuilder) where T : class
  4. {
  5. propertyBuilder
  6. .HasConversion(new JsonValueConverter<T>());
  7. return propertyBuilder;
  8. }
  9. }

A następnie użyć jej podczas konfiguracji

  1. builder.Property(p => p.ShippingAddress)
  2. .HasJsonValueConversion();

Dokumentacja

Linki

https://github.com/Innofactor/EfCoreJsonValueConverter