Skip to content

Commit 2de4ef8

Browse files
committed
FIX: Managed properties are returned as ManagedProperty<T> (or BooleanManagedProperty)
1 parent 760a0d9 commit 2de4ef8

7 files changed

Lines changed: 93 additions & 94 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
namespace DataverseProxyGenerator.Core.Domain;
2+
3+
public record BooleanManagedColumnModel() : ManagedColumnModel("bool", IsNullable: false)
4+
{
5+
}

src/DataverseProxyGenerator.Core/Domain/ColumnModel.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,5 @@ public abstract record ColumnModel
1212

1313
public bool IsObsolete { get; init; }
1414

15-
public bool IsReadOnly { get; init; }
16-
1715
public string TypeName => GetType().Name;
1816
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace DataverseProxyGenerator.Core.Domain;
2+
3+
public record ManagedColumnModel(string ReturnType, bool IsNullable) : ColumnModel
4+
{
5+
public string FullReturnType => IsNullable && ReturnType != "string" ? ReturnType + "?" : ReturnType;
6+
}

src/DataverseProxyGenerator.Core/Metadata/DataverseMetadataFetcher.cs

Lines changed: 28 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -454,67 +454,40 @@ private static Dictionary<int, Dictionary<int, string>> BuildOptionLocalizations
454454
Description = ApplyLabelMapping(attr.Description?.UserLocalizedLabel?.Label ?? string.Empty),
455455
};
456456

457-
private ColumnModel? BuildManagedPropertyColumn(ManagedPropertyAttributeMetadata attr)
457+
private ManagedColumnModel? BuildManagedPropertyColumn(ManagedPropertyAttributeMetadata attr)
458458
{
459-
ColumnModel? column = attr.ValueAttributeTypeCode switch
459+
return attr.ValueAttributeTypeCode switch
460460
{
461-
AttributeTypeCode.Boolean => BuildBooleanColumn(new BooleanAttributeMetadata(attr.SchemaName)
462-
{
463-
LogicalName = attr.LogicalName,
464-
}),
465-
AttributeTypeCode.DateTime => BuildDateTimeColumn(new DateTimeAttributeMetadata(null, attr.SchemaName)
466-
{
467-
LogicalName = attr.LogicalName,
468-
}),
469-
AttributeTypeCode.Decimal => BuildDecimalColumn(new DecimalAttributeMetadata(attr.SchemaName)
470-
{
471-
LogicalName = attr.LogicalName,
472-
}),
473-
AttributeTypeCode.Double => BuildDoubleColumn(new DoubleAttributeMetadata(attr.SchemaName)
474-
{
475-
LogicalName = attr.LogicalName,
476-
}),
477-
AttributeTypeCode.Integer => BuildIntegerColumn(new IntegerAttributeMetadata(attr.SchemaName)
478-
{
479-
LogicalName = attr.LogicalName,
480-
}),
481-
AttributeTypeCode.BigInt => BuildBigIntColumn(new BigIntAttributeMetadata(attr.SchemaName)
482-
{
483-
LogicalName = attr.LogicalName,
484-
}),
485-
AttributeTypeCode.Lookup => BuildLookupColumn(new LookupAttributeMetadata
486-
{
487-
LogicalName = attr.LogicalName,
488-
SchemaName = attr.SchemaName,
489-
}),
490-
AttributeTypeCode.Money => BuildMoneyColumn(new MoneyAttributeMetadata(attr.SchemaName)
491-
{
492-
LogicalName = attr.LogicalName,
493-
}),
494-
AttributeTypeCode.Memo => BuildMemoColumn(new MemoAttributeMetadata(attr.SchemaName)
495-
{
496-
LogicalName = attr.LogicalName,
497-
}),
498-
AttributeTypeCode.PartyList => BuildPartyListColumn(new LookupAttributeMetadata
499-
{
500-
LogicalName = attr.LogicalName,
501-
SchemaName = attr.SchemaName,
502-
}),
503-
AttributeTypeCode.String => BuildStringColumn(new StringAttributeMetadata(attr.SchemaName)
504-
{
505-
LogicalName = attr.LogicalName,
506-
}),
461+
AttributeTypeCode.Boolean => BuildBooleanManagedColumnModel(attr),
462+
AttributeTypeCode.DateTime => BuildManagedColumnModel(attr, "DateTime", nullable: true),
463+
AttributeTypeCode.Decimal => BuildManagedColumnModel(attr, "decimal", nullable: true),
464+
AttributeTypeCode.Double => BuildManagedColumnModel(attr, "double", nullable: true),
465+
AttributeTypeCode.Integer => BuildManagedColumnModel(attr, "int", nullable: true),
466+
AttributeTypeCode.BigInt => BuildManagedColumnModel(attr, "long", nullable: true),
467+
AttributeTypeCode.Lookup => BuildManagedColumnModel(attr, "EntityReference", nullable: true),
468+
AttributeTypeCode.Money => BuildManagedColumnModel(attr, "decimal", nullable: true),
469+
AttributeTypeCode.Memo => BuildManagedColumnModel(attr, "string"),
470+
AttributeTypeCode.PartyList => BuildManagedColumnModel(attr, "IEnumerable<ActivityParty>"),
471+
AttributeTypeCode.String => BuildManagedColumnModel(attr, "string"),
507472
_ => null,
508473
};
474+
}
509475

510-
if (column is null)
511-
return column;
476+
private ManagedColumnModel BuildManagedColumnModel(AttributeMetadata attr, string returnType, bool nullable = false) => new ManagedColumnModel(returnType, nullable)
477+
{
478+
LogicalName = attr.LogicalName,
479+
SchemaName = attr.SchemaName,
480+
DisplayName = ApplyLabelMapping(attr.DisplayName?.UserLocalizedLabel?.Label ?? attr.LogicalName),
481+
Description = ApplyLabelMapping(attr.Description?.UserLocalizedLabel?.Label ?? string.Empty),
482+
};
512483

513-
return column with
514-
{
515-
IsReadOnly = true,
516-
};
517-
}
484+
private BooleanManagedColumnModel BuildBooleanManagedColumnModel(AttributeMetadata attr) => new BooleanManagedColumnModel
485+
{
486+
LogicalName = attr.LogicalName,
487+
SchemaName = attr.SchemaName,
488+
DisplayName = ApplyLabelMapping(attr.DisplayName?.UserLocalizedLabel?.Label ?? attr.LogicalName),
489+
Description = ApplyLabelMapping(attr.Description?.UserLocalizedLabel?.Label ?? string.Empty),
490+
};
518491

519492
private UniqueIdentifierColumnModel BuildUniqueIdentifierColumn(AttributeMetadata attr) => new UniqueIdentifierColumnModel
520493
{

src/DataverseProxyGenerator.Core/Templates/Body/EntityClass.scriban-cs

Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,6 @@ public partial class {{table.SchemaName}} : ExtendedEntity{{ if table.Interfaces
4141
{{~ if column.DisplayName ~}}
4242
/// <para>Display Name: {{ column.DisplayName }}</para>
4343
{{~ end ~}}
44-
{{~ if column.IsReadOnly ~}}
45-
/// <para>This column is managed and therefore read-only.</para>
46-
{{~ end ~}}
4744
/// </summary>
4845
{{~ end ~}}
4946
[AttributeLogicalName("{{ column.LogicalName }}")]
@@ -56,102 +53,100 @@ public partial class {{table.SchemaName}} : ExtendedEntity{{ if table.Interfaces
5653
public string {{column.SchemaName}}
5754
{
5855
get => GetAttributeValue<string>("{{column.LogicalName}}");
59-
{{~ if !column.IsReadOnly ~}}
60-
set => SetAttributeValue("{{column.LogicalName}}", value);{{~ end}}
56+
set => SetAttributeValue("{{column.LogicalName}}", value);
6157
}
6258
{{~ else if column.TypeName == "IntegerColumnModel" ~}}
6359
[Range({{ column.Min }}, {{ column.Max }})]
6460
public int? {{column.SchemaName}}
6561
{
6662
get => GetAttributeValue<int?>("{{column.LogicalName}}");
67-
{{~ if !column.IsReadOnly ~}}
68-
set => SetAttributeValue("{{column.LogicalName}}", value);{{~ end}}
63+
set => SetAttributeValue("{{column.LogicalName}}", value);
6964
}
7065
{{~ else if column.TypeName == "BigIntColumnModel" ~}}
7166
public long? {{column.SchemaName}}
7267
{
7368
get => GetAttributeValue<long?>("{{column.LogicalName}}");
74-
{{~ if !column.IsReadOnly ~}}
75-
set => SetAttributeValue("{{column.LogicalName}}", value);{{~ end}}
69+
set => SetAttributeValue("{{column.LogicalName}}", value);
7670
}
7771
{{~ else if column.TypeName == "BooleanColumnModel" ~}}
7872
public bool? {{column.SchemaName}}
7973
{
8074
get => GetAttributeValue<bool?>("{{column.LogicalName}}");
81-
{{~ if !column.IsReadOnly ~}}
82-
set => SetAttributeValue("{{column.LogicalName}}", value);{{~ end}}
75+
set => SetAttributeValue("{{column.LogicalName}}", value);
8376
}
8477
{{~ else if column.TypeName == "DateTimeColumnModel" ~}}
8578
public DateTime? {{column.SchemaName}}
8679
{
8780
get => GetAttributeValue<DateTime?>("{{column.LogicalName}}");
88-
{{~ if !column.IsReadOnly ~}}
89-
set => SetAttributeValue("{{column.LogicalName}}", value);{{~ end}}
81+
set => SetAttributeValue("{{column.LogicalName}}", value);
9082
}
9183
{{~ else if column.TypeName == "DecimalColumnModel" ~}}
9284
public decimal? {{column.SchemaName}}
9385
{
9486
get => GetAttributeValue<decimal?>("{{column.LogicalName}}");
95-
{{~ if !column.IsReadOnly ~}}
96-
set => SetAttributeValue("{{column.LogicalName}}", value);{{~ end}}
87+
set => SetAttributeValue("{{column.LogicalName}}", value);
9788
}
9889
{{~ else if column.TypeName == "DoubleColumnModel" ~}}
9990
public double? {{column.SchemaName}}
10091
{
10192
get => GetAttributeValue<double?>("{{column.LogicalName}}");
102-
{{~ if !column.IsReadOnly ~}}
103-
set => SetAttributeValue("{{column.LogicalName}}", value);{{~ end}}
93+
set => SetAttributeValue("{{column.LogicalName}}", value);
10494
}
10595
{{~ else if column.TypeName == "MoneyColumnModel" ~}}
10696
public decimal? {{column.SchemaName}}
10797
{
10898
get => this.GetMoneyValue("{{column.LogicalName}}");
109-
{{~ if !column.IsReadOnly ~}}
110-
set => this.SetMoneyValue("{{column.LogicalName}}", value);{{~ end}}
99+
set => this.SetMoneyValue("{{column.LogicalName}}", value);
111100
}
112101
{{~ else if column.TypeName == "EnumColumnModel" ~}}
113102
{{~ if column.IsMultiSelect ~}}
114103
public IEnumerable<{{ column.OptionsetName }}> {{column.SchemaName}}
115104
{
116105
get => this.GetOptionSetCollectionValue<{{ column.OptionsetName }}>("{{column.LogicalName}}");
117-
{{~ if !column.IsReadOnly ~}}
118-
set => this.SetOptionSetCollectionValue("{{column.LogicalName}}", value);{{~ end}}
106+
set => this.SetOptionSetCollectionValue("{{column.LogicalName}}", value);
119107
}
120108
{{~ else ~}}
121109
public {{ column.OptionsetName }}? {{column.SchemaName}}
122110
{
123111
get => this.GetOptionSetValue<{{ column.OptionsetName }}>("{{column.LogicalName}}");
124-
{{~ if !column.IsReadOnly ~}}
125-
set => this.SetOptionSetValue("{{column.LogicalName}}", value);{{~ end}}
112+
set => this.SetOptionSetValue("{{column.LogicalName}}", value);
126113
}
127114
{{~ end ~}}
128115
{{~ else if column.TypeName == "LookupColumnModel" ~}}
129116
public EntityReference? {{column.SchemaName}}
130117
{
131118
get => GetAttributeValue<EntityReference?>("{{column.LogicalName}}");
132-
{{~ if !column.IsReadOnly ~}}
133-
set => SetAttributeValue("{{column.LogicalName}}", value);{{~ end}}
119+
set => SetAttributeValue("{{column.LogicalName}}", value);
134120
}
135121
{{~ else if column.TypeName == "PartyListColumnModel" ~}}
136122
public IEnumerable<ActivityParty> {{column.SchemaName}}
137123
{
138124
get => GetEntityCollection<ActivityParty>("{{column.LogicalName}}");
139-
{{~ if !column.IsReadOnly ~}}
140-
set => SetEntityCollection("{{column.LogicalName}}", value);{{~ end}}
125+
set => SetEntityCollection("{{column.LogicalName}}", value);
141126
}
142127
{{~ else if column.TypeName == "FileColumnModel" || column.TypeName == "ImageColumnModel" ~}}
143128
public byte[] {{column.SchemaName}}
144129
{
145130
get => GetAttributeValue<byte[]>("{{column.LogicalName}}");
146-
{{~ if !column.IsReadOnly ~}}
147-
set => SetAttributeValue("{{column.LogicalName}}", value);{{~ end}}
131+
set => SetAttributeValue("{{column.LogicalName}}", value);
148132
}
149133
{{~ else if column.TypeName == "UniqueIdentifierColumnModel" ~}}
150134
public Guid? {{column.SchemaName}}
151135
{
152136
get => GetAttributeValue<Guid?>("{{column.LogicalName}}");
153-
{{~ if !column.IsReadOnly ~}}
154-
set => SetAttributeValue("{{column.LogicalName}}", value);{{~ end}}
137+
set => SetAttributeValue("{{column.LogicalName}}", value);
138+
}
139+
{{~ else if column.TypeName == "BooleanManagedColumnModel" ~}}
140+
public BooleanManagedProperty {{column.SchemaName}}
141+
{
142+
get => GetAttributeValue<BooleanManagedProperty>("{{column.LogicalName}}");
143+
set => SetAttributeValue("{{column.LogicalName}}", value);
144+
}
145+
{{~ else if column.TypeName == "ManagedColumnModel" ~}}
146+
public ManagedProperty<{{column.FullReturnType}}> {{column.SchemaName}}
147+
{
148+
get => GetAttributeValue<ManagedProperty<{{column.FullReturnType}}>>("{{column.LogicalName}}");
149+
set => SetAttributeValue("{{column.LogicalName}}", value);
155150
}
156151
{{~ else if column.TypeName == "PrimaryIdColumnModel" ~}}
157152
public Guid {{column.SchemaName}}

tests/DataverseProxyGenerator.Tests/AttributeTypeCodeGenTests.Generates_Correct_Code_For_All_AttributeTypes.verified.txt

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,28 @@ public partial class TestEntity : ExtendedEntity
115115
set => SetAttributeValue("isactive", value);
116116
}
117117

118+
/// <summary>
119+
/// <para>Display Name: A Managed Boolean Attribute</para>
120+
/// </summary>
121+
[AttributeLogicalName("managedbooleanattribute")]
122+
[DisplayName("A Managed Boolean Attribute")]
123+
public BooleanManagedProperty ManagedBooleanAttribute
124+
{
125+
get => GetAttributeValue<BooleanManagedProperty>("managedbooleanattribute");
126+
set => SetAttributeValue("managedbooleanattribute", value);
127+
}
128+
129+
/// <summary>
130+
/// <para>Display Name: A Managed DateTime Attribute</para>
131+
/// </summary>
132+
[AttributeLogicalName("manageddatetimeattribute")]
133+
[DisplayName("A Managed DateTime Attribute")]
134+
public ManagedProperty<DateTime?> ManagedDateTimeAttribute
135+
{
136+
get => GetAttributeValue<ManagedProperty<DateTime?>>("manageddatetimeattribute");
137+
set => SetAttributeValue("manageddatetimeattribute", value);
138+
}
139+
118140
/// <summary>
119141
/// <para>Display Name: Name</para>
120142
/// </summary>
@@ -199,15 +221,13 @@ public partial class TestEntity : ExtendedEntity
199221

200222
/// <summary>
201223
/// <para>Display Name: A ReadOnly Attribute</para>
202-
/// <para>This column is managed and therefore read-only.</para>
203224
/// </summary>
204225
[AttributeLogicalName("readonlyattribute")]
205226
[DisplayName("A ReadOnly Attribute")]
206-
[MaxLength()]
207-
public string ReadOnlyAttribute
227+
public ManagedProperty<string> ReadOnlyAttribute
208228
{
209-
get => GetAttributeValue<string>("readonlyattribute");
210-
229+
get => GetAttributeValue<ManagedProperty<string>>("readonlyattribute");
230+
set => SetAttributeValue("readonlyattribute", value);
211231
}
212232

213233
/// <summary>

tests/DataverseProxyGenerator.Tests/AttributeTypeCodeGenTests.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ public async Task Generates_Correct_Code_For_All_AttributeTypes()
1515
DisplayName = "Test Entity",
1616
Columns = new List<ColumnModel>
1717
{
18-
new StringColumnModel { LogicalName = "readonlyattribute", SchemaName = "ReadOnlyAttribute", DisplayName = "A ReadOnly Attribute", IsReadOnly = true },
18+
new ManagedColumnModel("string", IsNullable: false) { LogicalName = "readonlyattribute", SchemaName = "ReadOnlyAttribute", DisplayName = "A ReadOnly Attribute" },
19+
new BooleanManagedColumnModel { LogicalName = "managedbooleanattribute", SchemaName = "ManagedBooleanAttribute", DisplayName = "A Managed Boolean Attribute" },
20+
new ManagedColumnModel("DateTime", IsNullable: true) { LogicalName = "manageddatetimeattribute", SchemaName = "ManagedDateTimeAttribute", DisplayName = "A Managed DateTime Attribute" },
1921
new StringColumnModel { LogicalName = "obsoleteattribute", SchemaName = "ObsoleteAttribute", DisplayName = "An Obsolete Attribute", IsObsolete = true },
2022
new StringColumnModel { LogicalName = "name", SchemaName = "Name", DisplayName = "Name" },
2123
new StringColumnModel { LogicalName = "prefix_pascalcasetest_withname", SchemaName = "prefix_pascalCaseTest_withName", DisplayName = "Pascal Test" },

0 commit comments

Comments
 (0)