Skip to content

Commit

Permalink
Simplify HasConversion API by allowing provider type and converter ty…
Browse files Browse the repository at this point in the history
…pe to be used interchangeably

Fixes #25468
  • Loading branch information
AndriySvyryd committed Aug 13, 2021
1 parent 5d9ae8d commit b112459
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 105 deletions.
56 changes: 35 additions & 21 deletions src/EFCore/Metadata/Builders/PropertiesConfigurationBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,53 +115,67 @@ public virtual PropertiesConfigurationBuilder AreUnicode(bool unicode = true)
}

/// <summary>
/// Configures the property so that the property value is converted to the given type before
/// Configures the property so that the property value is converted before
/// writing to the database and converted back when reading from the database.
/// </summary>
/// <typeparam name="TProvider"> The type to convert to and from. </typeparam>
/// <typeparam name="TConversion"> The type to convert to and from or a type that derives from <see cref="ValueConverter"/>. </typeparam>
/// <returns> The same builder instance so that multiple configuration calls can be chained. </returns>
public virtual PropertiesConfigurationBuilder HaveConversion<TProvider>()
=> HaveConversion(typeof(TProvider));
public virtual PropertiesConfigurationBuilder HaveConversion<TConversion>()
=> HaveConversion(typeof(TConversion));

/// <summary>
/// Configures the property so that the property value is converted to the given type before
/// Configures the property so that the property value is converted before
/// writing to the database and converted back when reading from the database.
/// </summary>
/// <param name="providerClrType"> The type to convert to and from. </param>
/// <param name="conversionType"> The type to convert to and from or a type that derives from <see cref="ValueConverter"/>. </param>
/// <returns> The same builder instance so that multiple configuration calls can be chained. </returns>
public virtual PropertiesConfigurationBuilder HaveConversion(Type providerClrType)
public virtual PropertiesConfigurationBuilder HaveConversion(Type conversionType)
{
Check.NotNull(providerClrType, nameof(providerClrType));
Check.NotNull(conversionType, nameof(conversionType));

Property.SetProviderClrType(providerClrType);
if (typeof(ValueConverter).IsAssignableFrom(conversionType))
{
Property.SetValueConverter(conversionType);
}
else
{
Property.SetProviderClrType(conversionType);
}

return this;
}

/// <summary>
/// Configures the property so that the property value is converted to and from the database
/// using the given <see cref="ValueConverter" />.
/// Configures the property so that the property value is converted before
/// writing to the database and converted back when reading from the database.
/// </summary>
/// <typeparam name="TConverter"> A type that derives from <see cref="ValueConverter"/>. </typeparam>
/// <typeparam name="TConversion"> The type to convert to and from or a type that derives from <see cref="ValueConverter"/>. </typeparam>
/// <typeparam name="TComparer"> A type that derives from <see cref="ValueComparer"/>. </typeparam>
/// <returns> The same builder instance so that multiple configuration calls can be chained. </returns>
public virtual PropertiesConfigurationBuilder HaveConversion<TConverter, TComparer>()
where TConverter : ValueConverter
public virtual PropertiesConfigurationBuilder HaveConversion<TConversion, TComparer>()
where TComparer : ValueComparer
=> HaveConversion(typeof(TConverter), typeof(TComparer));
=> HaveConversion(typeof(TConversion), typeof(TComparer));

/// <summary>
/// Configures the property so that the property value is converted to and from the database
/// using the given <see cref="ValueConverter" />.
/// Configures the property so that the property value is converted before
/// writing to the database and converted back when reading from the database.
/// </summary>
/// <param name="converterType"> A type that derives from <see cref="ValueConverter"/>. </param>
/// <param name="conversionType"> The type to convert to and from or a type that derives from <see cref="ValueConverter"/>. </param>
/// <param name="comparerType"> A type that derives from <see cref="ValueComparer"/>. </param>
/// <returns> The same builder instance so that multiple configuration calls can be chained. </returns>
public virtual PropertiesConfigurationBuilder HaveConversion(Type converterType, Type? comparerType)
public virtual PropertiesConfigurationBuilder HaveConversion(Type conversionType, Type? comparerType)
{
Check.NotNull(converterType, nameof(converterType));
Check.NotNull(conversionType, nameof(conversionType));

if (typeof(ValueConverter).IsAssignableFrom(conversionType))
{
Property.SetValueConverter(conversionType);
}
else
{
Property.SetProviderClrType(conversionType);
}

Property.SetValueConverter(converterType);
Property.SetValueComparer(comparerType);

return this;
Expand Down
37 changes: 18 additions & 19 deletions src/EFCore/Metadata/Builders/PropertiesConfigurationBuilder`.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,43 +80,42 @@ public PropertiesConfigurationBuilder(PropertyConfiguration property)
=> (PropertiesConfigurationBuilder<TProperty>)base.AreUnicode(unicode);

/// <summary>
/// Configures the property so that the property value is converted to the given type before
/// Configures the property so that the property value is converted before
/// writing to the database and converted back when reading from the database.
/// </summary>
/// <typeparam name="TProvider"> The type to convert to and from. </typeparam>
/// <typeparam name="TConversion"> The type to convert to and from or a type that derives from <see cref="ValueConverter"/>. </typeparam>
/// <returns> The same builder instance so that multiple configuration calls can be chained. </returns>
public new virtual PropertiesConfigurationBuilder<TProperty> HaveConversion<TProvider>()
=> (PropertiesConfigurationBuilder<TProperty>)base.HaveConversion<TProvider>();
public new virtual PropertiesConfigurationBuilder<TProperty> HaveConversion<TConversion>()
=> (PropertiesConfigurationBuilder<TProperty>)base.HaveConversion<TConversion>();

/// <summary>
/// Configures the property so that the property value is converted to the given type before
/// Configures the property so that the property value is converted before
/// writing to the database and converted back when reading from the database.
/// </summary>
/// <param name="providerClrType"> The type to convert to and from. </param>
/// <param name="conversionType"> The type to convert to and from or a type that derives from <see cref="ValueConverter"/>. </param>
/// <returns> The same builder instance so that multiple configuration calls can be chained. </returns>
public new virtual PropertiesConfigurationBuilder<TProperty> HaveConversion(Type providerClrType)
=> (PropertiesConfigurationBuilder<TProperty>)base.HaveConversion(providerClrType);
public new virtual PropertiesConfigurationBuilder<TProperty> HaveConversion(Type conversionType)
=> (PropertiesConfigurationBuilder<TProperty>)base.HaveConversion(conversionType);

/// <summary>
/// Configures the property so that the property value is converted to and from the database
/// using the given <see cref="ValueConverter" />.
/// Configures the property so that the property value is converted before
/// writing to the database and converted back when reading from the database.
/// </summary>
/// <typeparam name="TConverter"> A type that derives from <see cref="ValueConverter"/>. </typeparam>
/// <typeparam name="TConversion"> The type to convert to and from or a type that derives from <see cref="ValueConverter"/>. </typeparam>
/// <typeparam name="TComparer"> A type that derives from <see cref="ValueComparer"/>. </typeparam>
/// <returns> The same builder instance so that multiple configuration calls can be chained. </returns>
public new virtual PropertiesConfigurationBuilder<TProperty> HaveConversion<TConverter, TComparer>()
where TConverter : ValueConverter
public new virtual PropertiesConfigurationBuilder<TProperty> HaveConversion<TConversion, TComparer>()
where TComparer : ValueComparer
=> (PropertiesConfigurationBuilder<TProperty>)base.HaveConversion<TConverter, TComparer>();
=> (PropertiesConfigurationBuilder<TProperty>)base.HaveConversion<TConversion, TComparer>();

/// <summary>
/// Configures the property so that the property value is converted to and from the database
/// using the given <see cref="ValueConverter" />.
/// Configures the property so that the property value is converted before
/// writing to the database and converted back when reading from the database.
/// </summary>
/// <param name="converterType"> A type that derives from <see cref="ValueConverter"/>. </param>
/// <param name="conversionType"> The type to convert to and from or a type that derives from <see cref="ValueConverter"/>. </param>
/// <param name="comparerType"> A type that derives from <see cref="ValueComparer"/>. </param>
/// <returns> The same builder instance so that multiple configuration calls can be chained. </returns>
public new virtual PropertiesConfigurationBuilder<TProperty> HaveConversion(Type converterType, Type? comparerType)
=> (PropertiesConfigurationBuilder<TProperty>)base.HaveConversion(converterType, comparerType);
public new virtual PropertiesConfigurationBuilder<TProperty> HaveConversion(Type conversionType, Type? comparerType)
=> (PropertiesConfigurationBuilder<TProperty>)base.HaveConversion(conversionType, comparerType);
}
}
80 changes: 51 additions & 29 deletions src/EFCore/Metadata/Builders/PropertyBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -440,23 +440,30 @@ public virtual PropertyBuilder UsePropertyAccessMode(PropertyAccessMode property
}

/// <summary>
/// Configures the property so that the property value is converted to the given type before
/// Configures the property so that the property value is converted before
/// writing to the database and converted back when reading from the database.
/// </summary>
/// <typeparam name="TProvider"> The type to convert to and from. </typeparam>
/// <typeparam name="TConversion"> The type to convert to and from or a type that derives from <see cref="ValueConverter"/>. </typeparam>
/// <returns> The same builder instance so that multiple configuration calls can be chained. </returns>
public virtual PropertyBuilder HasConversion<TProvider>()
=> HasConversion(typeof(TProvider));
public virtual PropertyBuilder HasConversion<TConversion>()
=> HasConversion(typeof(TConversion));

/// <summary>
/// Configures the property so that the property value is converted to the given type before
/// Configures the property so that the property value is converted before
/// writing to the database and converted back when reading from the database.
/// </summary>
/// <param name="providerClrType"> The type to convert to and from. </param>
/// <param name="conversionType"> The type to convert to and from or a type that derives from <see cref="ValueConverter"/>. </param>
/// <returns> The same builder instance so that multiple configuration calls can be chained. </returns>
public virtual PropertyBuilder HasConversion(Type? providerClrType)
public virtual PropertyBuilder HasConversion(Type? conversionType)
{
Builder.HasConversion(providerClrType, ConfigurationSource.Explicit);
if (typeof(ValueConverter).IsAssignableFrom(conversionType))
{
Builder.HasConverter(conversionType, ConfigurationSource.Explicit);
}
else
{
Builder.HasConversion(conversionType, ConfigurationSource.Explicit);
}

return this;
}
Expand All @@ -475,27 +482,35 @@ public virtual PropertyBuilder HasConversion(ValueConverter? converter)
}

/// <summary>
/// Configures the property so that the property value is converted to the given type before
/// Configures the property so that the property value is converted before
/// writing to the database and converted back when reading from the database.
/// </summary>
/// <param name="valueComparer"> The comparer to use for values before conversion. </param>
/// <typeparam name="TProvider"> The type to convert to and from. </typeparam>
/// <typeparam name="TConversion"> The type to convert to and from or a type that derives from <see cref="ValueConverter"/>. </typeparam>
/// <returns> The same builder instance so that multiple configuration calls can be chained. </returns>
public virtual PropertyBuilder HasConversion<TProvider>(ValueComparer? valueComparer)
=> HasConversion(typeof(TProvider), valueComparer);
public virtual PropertyBuilder HasConversion<TConversion>(ValueComparer? valueComparer)
=> HasConversion(typeof(TConversion), valueComparer);

/// <summary>
/// Configures the property so that the property value is converted to the given type before
/// Configures the property so that the property value is converted before
/// writing to the database and converted back when reading from the database.
/// </summary>
/// <param name="providerClrType"> The type to convert to and from. </param>
/// <param name="conversionType"> The type to convert to and from or a type that derives from <see cref="ValueConverter"/>. </param>
/// <param name="valueComparer"> The comparer to use for values before conversion. </param>
/// <returns> The same builder instance so that multiple configuration calls can be chained. </returns>
public virtual PropertyBuilder HasConversion(Type providerClrType, ValueComparer? valueComparer)
public virtual PropertyBuilder HasConversion(Type conversionType, ValueComparer? valueComparer)
{
Check.NotNull(providerClrType, nameof(providerClrType));
Check.NotNull(conversionType, nameof(conversionType));

if (typeof(ValueConverter).IsAssignableFrom(conversionType))
{
Builder.HasConverter(conversionType, ConfigurationSource.Explicit);
}
else
{
Builder.HasConversion(conversionType, ConfigurationSource.Explicit);
}

Builder.HasConversion(providerClrType, ConfigurationSource.Explicit);
Builder.HasValueComparer(valueComparer, ConfigurationSource.Explicit);

return this;
Expand All @@ -517,29 +532,36 @@ public virtual PropertyBuilder HasConversion(ValueConverter? converter, ValueCom
}

/// <summary>
/// Configures the property so that the property value is converted to and from the database
/// using the given <see cref="ValueConverter" />.
/// Configures the property so that the property value is converted before
/// writing to the database and converted back when reading from the database.
/// </summary>
/// <typeparam name="TConverter"> A type that derives from <see cref="ValueConverter"/>. </typeparam>
/// <typeparam name="TConversion"> The type to convert to and from or a type that derives from <see cref="ValueConverter"/>. </typeparam>
/// <typeparam name="TComparer"> A type that derives from <see cref="ValueComparer"/>. </typeparam>
/// <returns> The same builder instance so that multiple configuration calls can be chained. </returns>
public virtual PropertyBuilder HasConversion<TConverter, TComparer>()
where TConverter : ValueConverter
public virtual PropertyBuilder HasConversion<TConversion, TComparer>()
where TComparer : ValueComparer
=> HasConversion(typeof(TConverter), typeof(TComparer));
=> HasConversion(typeof(TConversion), typeof(TComparer));

/// <summary>
/// Configures the property so that the property value is converted to and from the database
/// using the given <see cref="ValueConverter" />.
/// Configures the property so that the property value is converted before
/// writing to the database and converted back when reading from the database.
/// </summary>
/// <param name="converterType"> A type that derives from <see cref="ValueConverter"/>. </param>
/// <param name="conversionType"> The type to convert to and from or a type that derives from <see cref="ValueConverter"/>. </param>
/// <param name="comparerType"> A type that derives from <see cref="ValueComparer"/>. </param>
/// <returns> The same builder instance so that multiple configuration calls can be chained. </returns>
public virtual PropertyBuilder HasConversion(Type converterType, Type? comparerType)
public virtual PropertyBuilder HasConversion(Type conversionType, Type? comparerType)
{
Check.NotNull(converterType, nameof(converterType));
Check.NotNull(conversionType, nameof(conversionType));

if (typeof(ValueConverter).IsAssignableFrom(conversionType))
{
Builder.HasConverter(conversionType, ConfigurationSource.Explicit);
}
else
{
Builder.HasConversion(conversionType, ConfigurationSource.Explicit);
}

Builder.HasConverter(converterType, ConfigurationSource.Explicit);
Builder.HasValueComparer(comparerType, ConfigurationSource.Explicit);

return this;
Expand Down
Loading

0 comments on commit b112459

Please sign in to comment.