Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
{{#each property-annotations}}
{{{property-annotation}}}
{{/each}}
public {{property-type}} {{property-name}} { get; set; }{{#if nullable-reference-types }}{{#unless property-isnullable}} = null!;{{/unless}}{{/if}}
public {{property-type}} {{property-name}} { get; set; }{{#if nullable-reference-types }}{{#unless property-isnullable}} = null!;{{/unless}}{{else}}{{#if property-default-enum}} = {{property-default-enum}};{{/if}}{{/if}}
{{/each}}
{{#if nav-properties}}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,16 @@ public EntityPropertyInfo() { }
/// <param name="propertyType">Property type.</param>
/// <param name="propertyName">Property name.</param>
/// <param name="propertyIsNullable">Property is nullable.</param>
public EntityPropertyInfo(string propertyType, string propertyName, bool? propertyIsNullable = null)
/// <param name="isEnumPropertyType">Is Enumeration Property Type</param>
/// <param name="propertyDefaultEnumValue">Default Enumeration Value. Format will be EnumName.EnumValue</param>
public EntityPropertyInfo(string propertyType, string propertyName, bool? propertyIsNullable = null
, bool? isEnumPropertyType = false, string propertyDefaultEnumValue = null)
{
PropertyType = propertyType;
PropertyName = propertyName;
PropertyIsNullable = propertyIsNullable;
IsEnumPropertyType = isEnumPropertyType;
PropertyDefaultEnumValue = propertyDefaultEnumValue;
}

/// <summary>
Expand All @@ -37,5 +42,16 @@ public EntityPropertyInfo(string propertyType, string propertyName, bool? proper
/// Property is nullable.
/// </summary>
public bool? PropertyIsNullable { get; set; }
/// <summary>
/// Property Type is an Enumeration.
/// Used in TransformPropertyTypeIfEnumaration
/// for Many to Many Virtual EntityTypes
/// </summary>
public bool? IsEnumPropertyType { get; set; }
/// <summary>
/// Property Default Value when using Enumarations
/// Format will be EnumName.EnumValue
/// </summary>
public string PropertyDefaultEnumValue { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ protected virtual void GenerateOnModelCreating([NotNull] IModel model)

foreach (var entityType in model.GetScaffoldEntityTypes(_options.Value))
{
if (IsManyToManyJoinEntityType(entityType))
if (entityType.IsManyToManyJoinEntityType())
{
continue;
}
Expand Down Expand Up @@ -285,7 +285,7 @@ private void GenerateDbSets(IModel model)

foreach (var entityType in model.GetScaffoldEntityTypes(_options.Value))
{
if (IsManyToManyJoinEntityType(entityType))
if (entityType.IsManyToManyJoinEntityType())
{
continue;
}
Expand Down Expand Up @@ -683,8 +683,18 @@ private void GenerateProperty(IEntityType entityType, IProperty property, bool u
}
else if (defaultValue != null)
{
lines.Add(
$".{nameof(RelationalPropertyBuilderExtensions.HasDefaultValue)}({CSharpHelper.UnknownLiteral(defaultValue)})");
// Lookup Default Enum Value
var defaultEnumValue = EntityTypeTransformationService.TransformPropertyDefaultEnum(entityType, property.Name, property.DeclaringType.Name);
if (string.IsNullOrEmpty(defaultEnumValue))
{
lines.Add(
$".{nameof(RelationalPropertyBuilderExtensions.HasDefaultValue)}({CSharpHelper.UnknownLiteral(defaultValue)})");
}
else
{
lines.Add(
$".{nameof(RelationalPropertyBuilderExtensions.HasDefaultValue)}({defaultEnumValue})");
}
annotations.Remove(RelationalAnnotationNames.DefaultValue);
annotations.Remove(RelationalAnnotationNames.DefaultValueSql);
}
Expand Down Expand Up @@ -912,8 +922,18 @@ private void GenerateManyToMany(ISkipNavigation skipNavigation, IndentedStringBu

foreach (var property in joinEntityType.GetProperties())
{
lines.Add(
$"j.{nameof(EntityTypeBuilder.IndexerProperty)}<{CSharpHelper.Reference(property.ClrType)}>({CSharpHelper.Literal(property.Name)})");
// Lookup Property Type Transformation if it is an Enumeration
string enumPropertyType = EntityTypeTransformationService.TransformPropertyTypeIfEnumaration(joinEntityType, property.Name, property.DeclaringType.Name);
if (enumPropertyType == null)
{
lines.Add(
$"j.{nameof(EntityTypeBuilder.IndexerProperty)}<{CSharpHelper.Reference(property.ClrType)}>({CSharpHelper.Literal(property.Name)})");
}
else
{
lines.Add(
$"j.{nameof(EntityTypeBuilder.IndexerProperty)}<{enumPropertyType}>({CSharpHelper.Literal(property.Name)})");
}

var propertyAnnotations = AnnotationCodeGenerator
.FilterIgnoredAnnotations(property.GetAnnotations())
Expand Down Expand Up @@ -969,12 +989,14 @@ private void GenerateManyToMany(ISkipNavigation skipNavigation, IndentedStringBu
{
lines.Add($".{nameof(RelationalPropertyBuilderExtensions.HasDefaultValue)}()");
propertyAnnotations.Remove(RelationalAnnotationNames.DefaultValue);
propertyAnnotations.Remove(RelationalAnnotationNames.DefaultValueSql);
}
else if (defaultValue != null)
{
lines.Add(
$".{nameof(RelationalPropertyBuilderExtensions.HasDefaultValue)}({CSharpHelper.UnknownLiteral(defaultValue)})");
propertyAnnotations.Remove(RelationalAnnotationNames.DefaultValue);
propertyAnnotations.Remove(RelationalAnnotationNames.DefaultValueSql);
}
}

Expand Down Expand Up @@ -1204,30 +1226,5 @@ private string GenerateAnnotation(IAnnotation annotation)
=> $".HasAnnotation({CSharpHelper.Literal(annotation.Name)}, " +
$"{CSharpHelper.UnknownLiteral(annotation.Value)})";

private static bool IsManyToManyJoinEntityType(IEntityType entityType)
{
if (!entityType.GetNavigations().Any()
&& !entityType.GetSkipNavigations().Any())
{
var primaryKey = entityType.FindPrimaryKey();
var properties = entityType.GetProperties().ToList();
var foreignKeys = entityType.GetForeignKeys().ToList();
if (primaryKey != null
&& primaryKey.Properties.Count > 1
&& foreignKeys.Count == 2
&& primaryKey.Properties.Count == properties.Count
&& foreignKeys[0].Properties.Count + foreignKeys[1].Properties.Count == properties.Count
&& !foreignKeys[0].Properties.Intersect(foreignKeys[1].Properties).Any()
&& foreignKeys[0].IsRequired
&& foreignKeys[1].IsRequired
&& !foreignKeys[0].IsUnique
&& !foreignKeys[1].IsUnique)
{
return true;
}
}

return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,8 @@ protected virtual void GenerateProperties(IEntityType entityType)
{ "property-annotations", PropertyAnnotationsData },
{ "property-comment", _options?.Value?.GenerateComments == true ? GenerateComment(property.GetComment(), 2) : null },
{ "property-isnullable", propertyIsNullable },
{ "property-isenum", false },
{ "property-default-enum", null },
{ "nullable-reference-types", UseNullableReferenceTypes }
});
}
Expand Down Expand Up @@ -635,6 +637,11 @@ private void GenerateNavigationDataAnnotations(IEntityType entityType, INavigati
{
if (navigation == null) throw new ArgumentNullException(nameof(navigation));

if (navigation.ForeignKey.DeclaringEntityType.IsManyToManyJoinEntityType())
{
return;
}

GenerateForeignKeyAttribute(entityType, navigation);
GenerateInversePropertyAttribute(entityType, navigation);
}
Expand Down Expand Up @@ -697,6 +704,11 @@ private void GenerateNavigationDataAnnotations(IEntityType entityType, ISkipNavi
{
if (navigation == null) throw new ArgumentNullException(nameof(navigation));

if (navigation.ForeignKey.DeclaringEntityType.IsManyToManyJoinEntityType())
{
return;
}

GenerateForeignKeyAttribute(entityType, navigation);
GenerateInversePropertyAttribute(entityType, navigation);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace EntityFrameworkCore.Scaffolding.Handlebars
/// Default service for transforming entity type definitions.
/// </summary>
public abstract class HbsEntityTypeTransformationServiceBase : IEntityTypeTransformationService
{
{
/// <summary>
/// Entity name transformer.
/// </summary>
Expand Down Expand Up @@ -95,6 +95,48 @@ public string TransformPropertyName(IEntityType entityType, string propertyName,
return propertyName;
}

/// <summary>
/// Transforms the Property Type if it is an Enumeration.
/// Returns null when not an Enumeration
/// </summary>
/// <param name="entityType">Entity type.</param>
/// <param name="propertyName">Property name.</param>
/// <param name="propertyType">Property type</param>
/// <returns>Transformed property name, null when not an Enumeration</returns>
public string TransformPropertyTypeIfEnumaration(IEntityType entityType, string propertyName, string propertyType)
{
var propTypeInfo = new EntityPropertyInfo { PropertyName = propertyName, PropertyType = propertyType };
if (PropertyTransformer2 != null)
{
EntityPropertyInfo epi = PropertyTransformer2?.Invoke(entityType, propTypeInfo);
return epi.IsEnumPropertyType == true ? epi.PropertyType : null;
}
else if (PropertyTransformer != null)
{
EntityPropertyInfo epi = PropertyTransformer?.Invoke(propTypeInfo);
return epi.IsEnumPropertyType == true ? epi.PropertyType : null;
}
return null;
}

/// <summary>
/// Transform Default Enum Value for a property
/// </summary>
/// <param name="entityType">Entity type.</param>
/// <param name="propertyName">Property name.</param>
/// <param name="propertyType">Property type</param>
/// <returns>Default Enumeration Value in format Format will be EnumName.EnumValue</returns>
public string TransformPropertyDefaultEnum(IEntityType entityType, string propertyName, string propertyType)
{
var propTypeInfo = new EntityPropertyInfo { PropertyName = propertyName, PropertyType = propertyType };
if (PropertyTransformer2 != null)
return PropertyTransformer2?.Invoke(entityType, propTypeInfo)?.PropertyDefaultEnumValue;
else if (PropertyTransformer != null)
return PropertyTransformer?.Invoke(propTypeInfo)?.PropertyDefaultEnumValue;
else
return null;
}

/// <summary>
/// Transform single navigation property name.
/// </summary>
Expand Down Expand Up @@ -159,7 +201,9 @@ public List<Dictionary<string, object>> TransformProperties(IEntityType entityTy
{
var propTypeInfo = new EntityPropertyInfo(property["property-type"] as string,
property["property-name"] as string,
(property["property-isnullable"] as bool?) == true);
(property["property-isnullable"] as bool?) == true,
(property["property-isenum"] as bool?) == true,
property["property-default-enum"] as string);
EntityPropertyInfo transformedProp;
if (PropertyTransformer2 != null)
transformedProp = PropertyTransformer2?.Invoke(entityType, propTypeInfo);
Expand All @@ -170,6 +214,12 @@ public List<Dictionary<string, object>> TransformProperties(IEntityType entityTy
var propertyIsNullable = transformedProp.PropertyIsNullable != null
? transformedProp.PropertyIsNullable
: (bool)property["property-isnullable"];
var isEnumPropertyType = transformedProp.IsEnumPropertyType != null
? transformedProp.IsEnumPropertyType
: (bool)property["property-isenum"];
string propertyDefaultEnumValue = transformedProp.PropertyDefaultEnumValue != null
? transformedProp.PropertyDefaultEnumValue
: property["property-default-enum"] as string;

transformedProperties.Add(new Dictionary<string, object>
{
Expand All @@ -178,6 +228,8 @@ public List<Dictionary<string, object>> TransformProperties(IEntityType entityTy
{ "property-annotations", property["property-annotations"] },
{ "property-comment", property["property-comment"] },
{ "property-isnullable", propertyIsNullable },
{ "property-isenum", isEnumPropertyType },
{ "property-default-enum", propertyDefaultEnumValue },
{ "nullable-reference-types", property["nullable-reference-types"] }
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ protected virtual void GenerateProperties(IEntityType entityType)
{ "property-annotations", new List<Dictionary<string, object>>() },
{ "property-comment", property.GetComment() },
{ "property-isnullable", property.IsNullable },
{ "property-isenum", false },
{ "property-default-enum", null },
{ "nullable-reference-types", UseNullableReferenceTypes }
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,25 @@ public interface IEntityTypeTransformationService
/// <returns>Transformed property name.</returns>
string TransformNavPropertyName(IEntityType entityType, string propertyName, string propertyType);

/// <summary>
/// Transforms the Property Type if it is an Enumeration.
/// Returns null when not an Enumeration
/// </summary>
/// <param name="entityType">Entity type.</param>
/// <param name="propertyName">Property name.</param>
/// <param name="propertyType">Property type</param>
/// <returns>Transformed property name, null when not an Enumeration</returns>
public string TransformPropertyTypeIfEnumaration(IEntityType entityType, string propertyName, string propertyType);

/// <summary>
/// Transform Default Enum Value for a property
/// </summary>
/// <param name="entityType">Entity type.</param>
/// <param name="propertyName">Property name.</param>
/// <param name="propertyType">Property type</param>
/// <returns>Default Enumeration Value in format Format will be EnumName.EnumValue</returns>
public string TransformPropertyDefaultEnum(IEntityType entityType, string propertyName, string propertyType);

/// <summary>
/// Transform entity type constructor.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,36 @@ public static class EntityTypeExtensions
public static IEnumerable<IPropertyBase> GetPropertiesAndNavigations(
this IEntityType entityType)
=> entityType.GetProperties().Concat<IPropertyBase>(entityType.GetNavigations());

/// <summary>
/// Determines if the given <see cref="IEntityType"/> is a join entity
/// type for a many-to-many relationship where Entity would not be generated.
/// This is where only Key properties are present.
/// </summary>
/// <param name="entityType">Entity Type</param>
/// <returns></returns>
public static bool IsManyToManyJoinEntityType(this IEntityType entityType)
{
if (!entityType.GetNavigations().Any()
&& !entityType.GetSkipNavigations().Any())
{
var primaryKey = entityType.FindPrimaryKey();
var properties = entityType.GetProperties().ToList();
var foreignKeys = entityType.GetForeignKeys().ToList();
if (primaryKey != null
&& primaryKey.Properties.Count > 1
&& foreignKeys.Count == 2
&& primaryKey.Properties.Count == properties.Count
&& foreignKeys[0].Properties.Count + foreignKeys[1].Properties.Count == properties.Count
&& !foreignKeys[0].Properties.Intersect(foreignKeys[1].Properties).Any()
&& foreignKeys[0].IsRequired
&& foreignKeys[1].IsRequired
&& !foreignKeys[0].IsUnique
&& !foreignKeys[1].IsUnique)
{
return true;
}
}
return false;
}
}