Skip to content

Commit 2fba479

Browse files
committed
[01441] Auto-exclude navigation collection columns from DataTable scaffolding
1 parent 4ece9ff commit 2fba479

File tree

2 files changed

+105
-2
lines changed

2 files changed

+105
-2
lines changed
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
using Ivy;
2+
3+
namespace Ivy.Tests.Views.DataTables;
4+
5+
public class DataTableScaffoldTests
6+
{
7+
private class ChildEntity
8+
{
9+
public int Id { get; set; }
10+
public string Name { get; set; } = "";
11+
}
12+
13+
private class EntityWithICollection
14+
{
15+
public int Id { get; set; }
16+
public string Name { get; set; } = "";
17+
public ICollection<ChildEntity> Children { get; set; } = [];
18+
}
19+
20+
private class EntityWithList
21+
{
22+
public int Id { get; set; }
23+
public string Name { get; set; } = "";
24+
public List<ChildEntity> Children { get; set; } = [];
25+
}
26+
27+
private class EntityWithStringArray
28+
{
29+
public int Id { get; set; }
30+
public string Name { get; set; } = "";
31+
public string[] Tags { get; set; } = [];
32+
}
33+
34+
private class EntityWithListOfStrings
35+
{
36+
public int Id { get; set; }
37+
public string Name { get; set; } = "";
38+
public List<string> Tags { get; set; } = [];
39+
}
40+
41+
private class EntityWithPrimitives
42+
{
43+
public int Id { get; set; }
44+
public string Name { get; set; } = "";
45+
public DateTime CreatedAt { get; set; }
46+
public decimal Amount { get; set; }
47+
}
48+
49+
private static bool IsColumnRemoved<T>(DataTableBuilder<T> builder, string columnName)
50+
{
51+
var flags = System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance;
52+
var columnsField = builder.GetType().GetField("_columns", flags)!;
53+
var columnsObj = columnsField.GetValue(builder)!;
54+
var dictType = columnsObj.GetType();
55+
var itemProp = dictType.GetProperty("Item")!;
56+
var internalColumn = itemProp.GetValue(columnsObj, [columnName])!;
57+
var removedProp = internalColumn.GetType().GetProperty("Removed")!;
58+
return (bool)removedProp.GetValue(internalColumn)!;
59+
}
60+
61+
[Fact]
62+
public void Scaffold_ExcludesICollectionNavigationProperties()
63+
{
64+
var builder = new[] { new EntityWithICollection() }.AsQueryable().ToDataTable();
65+
Assert.True(IsColumnRemoved(builder, "Children"));
66+
}
67+
68+
[Fact]
69+
public void Scaffold_ExcludesListNavigationProperties()
70+
{
71+
var builder = new[] { new EntityWithList() }.AsQueryable().ToDataTable();
72+
Assert.True(IsColumnRemoved(builder, "Children"));
73+
}
74+
75+
[Fact]
76+
public void Scaffold_KeepsStringArrayAsLabels()
77+
{
78+
var builder = new[] { new EntityWithStringArray() }.AsQueryable().ToDataTable();
79+
Assert.False(IsColumnRemoved(builder, "Tags"));
80+
}
81+
82+
[Fact]
83+
public void Scaffold_KeepsListOfStrings()
84+
{
85+
var builder = new[] { new EntityWithListOfStrings() }.AsQueryable().ToDataTable();
86+
Assert.False(IsColumnRemoved(builder, "Tags"));
87+
}
88+
89+
[Fact]
90+
public void Scaffold_KeepsPrimitiveProperties()
91+
{
92+
var builder = new[] { new EntityWithPrimitives() }.AsQueryable().ToDataTable();
93+
Assert.False(IsColumnRemoved(builder, "Id"));
94+
Assert.False(IsColumnRemoved(builder, "Name"));
95+
Assert.False(IsColumnRemoved(builder, "CreatedAt"));
96+
Assert.False(IsColumnRemoved(builder, "Amount"));
97+
}
98+
}

src/Ivy/Views/DataTables/DataTableBuilder.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,13 @@ private void _Scaffold()
8383
align = Ivy.Align.Center;
8484
}
8585

86-
var removed = field.Name.StartsWith($"_") && field.Name.Length > 1 && char.IsLetter(field.Name[1]) ||
87-
field.Name == "_hiddenKey";
86+
var isNavigationCollection = field.Type.IsCollectionType() &&
87+
field.Type.GetCollectionTypeParameter() is { IsClass: true } elementType &&
88+
elementType != typeof(string);
89+
90+
var removed = field.Name.StartsWith("_") && field.Name.Length > 1 && char.IsLetter(field.Name[1]) ||
91+
field.Name == "_hiddenKey" ||
92+
isNavigationCollection;
8893

8994
_columns[field.Name] = new InternalColumn()
9095
{

0 commit comments

Comments
 (0)