• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

loresoft / EntityFrameworkCore.Generator / 27730465225

18 Jun 2026 01:21AM UTC coverage: 74.693% (+19.8%) from 54.885%
27730465225

push

github

pwelter34
update tests

922 of 1609 branches covered (57.3%)

Branch coverage included in aggregate %.

7 of 7 new or added lines in 2 files covered. (100.0%)

230 existing lines in 23 files now uncovered.

4007 of 4990 relevant lines covered (80.3%)

1258.69 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.24
/src/EntityFrameworkCore.Generator.Core/Templates/EntityClassTemplate.cs
1
using EntityFrameworkCore.Generator.Extensions;
2
using EntityFrameworkCore.Generator.Metadata.Generation;
3
using EntityFrameworkCore.Generator.Options;
4

5
namespace EntityFrameworkCore.Generator.Templates;
6

7
public class EntityClassTemplate : CodeTemplateBase
8
{
9
    private readonly Entity _entity;
10

11
    public EntityClassTemplate(Entity entity, GeneratorOptions options) : base(options)
160✔
12
    {
13
        _entity = entity;
160✔
14
    }
160✔
15

16
    public override string WriteCode()
17
    {
18
        CodeBuilder.Clear();
160✔
19

20
        if (Options.Data.Entity.Header.HasValue())
160!
UNCOV
21
            CodeBuilder.AppendLine(Options.Data.Entity.Header).AppendLine();
×
22

23
        CodeBuilder.AppendLine("using System;");
160✔
24
        CodeBuilder.AppendLine("using System.Collections.Generic;");
160✔
25
        if (Options.Data.Entity.MappingAttributes)
160✔
26
        {
27
            CodeBuilder.AppendLine("using System.ComponentModel.DataAnnotations;");
137✔
28
            CodeBuilder.AppendLine("using System.ComponentModel.DataAnnotations.Schema;");
137✔
29
        }
30
        CodeBuilder.AppendLine();
160✔
31

32
        CodeBuilder.Append($"namespace {_entity.EntityNamespace}");
160✔
33

34
        if (Options.Project.FileScopedNamespace)
160✔
35
        {
36
            CodeBuilder.AppendLine(";");
137✔
37
            CodeBuilder.AppendLine();
137✔
38
            GenerateClass();
137✔
39
        }
40
        else
41
        {
42
            CodeBuilder.AppendLine();
23✔
43
            CodeBuilder.AppendLine("{");
23✔
44

45
            using (CodeBuilder.Indent())
23✔
46
            {
47
                GenerateClass();
23✔
48
            }
23✔
49

50
            CodeBuilder.AppendLine("}");
23✔
51
        }
52

53
        return CodeBuilder.ToString();
160✔
54
    }
55

56
    private void GenerateClass()
57
    {
58
        var entityClass = _entity.EntityClass.ToSafeName();
160✔
59

60
        if (Options.Data.Entity.Document)
160✔
61
        {
62
            CodeBuilder.AppendLine("/// <summary>");
137✔
63
            CodeBuilder.AppendLine($"/// Entity class representing data for table <c>{_entity.TableName}</c>.");
137✔
64
            CodeBuilder.AppendLine("/// </summary>");
137✔
65
        }
66
        if (Options.Data.Entity.MappingAttributes)
160✔
67
        {
68
            if (_entity.TableSchema.HasValue())
137✔
69
                CodeBuilder.AppendLine($"[Table(\"{_entity.TableName}\", Schema = \"{_entity.TableSchema}\")]");
103✔
70
            else
71
                CodeBuilder.AppendLine($"[Table(\"{_entity.TableName}\")]");
34✔
72
        }
73
        CodeBuilder.AppendLine($"public partial class {entityClass}");
160✔
74

75
        if (_entity.EntityBaseClass.HasValue())
160!
76
        {
77
            var entityBaseClass = _entity.EntityBaseClass.ToSafeName();
×
78
            using (CodeBuilder.Indent())
×
UNCOV
79
                CodeBuilder.AppendLine($": {entityBaseClass}");
×
80
        }
81

82
        CodeBuilder.AppendLine("{");
160✔
83

84
        using (CodeBuilder.Indent())
160✔
85
        {
86
            GenerateConstructor();
160✔
87

88
            GenerateProperties();
160✔
89
            GenerateRelationshipProperties();
160✔
90
        }
160✔
91

92
        CodeBuilder.AppendLine("}");
160✔
93

94
    }
160✔
95

96
    private void GenerateConstructor()
97
    {
98
        var relationships = _entity.Relationships
160✔
99
            .Where(r => r.Cardinality == Cardinality.Many)
160✔
100
            .OrderBy(r => r.PropertyName)
160✔
101
            .ToList();
160✔
102

103
        var entityClass = _entity.EntityClass.ToSafeName();
160✔
104

105
        if (Options.Data.Entity.Document)
160✔
106
        {
107
            CodeBuilder.AppendLine("/// <summary>");
137✔
108
            CodeBuilder.AppendLine($"/// Initializes a new instance of the <see cref=\"{entityClass}\"/> class.");
137✔
109
            CodeBuilder.AppendLine("/// </summary>");
137✔
110
        }
111

112
        CodeBuilder.AppendLine($"public {entityClass}()");
160✔
113
        CodeBuilder.AppendLine("{");
160✔
114

115
        using (CodeBuilder.Indent())
160✔
116
        {
117
            CodeBuilder.AppendLine("#region Generated Constructor");
160✔
118
            foreach (var relationship in relationships)
462✔
119
            {
120
                var propertyName = relationship.PropertyName.ToSafeName();
71✔
121

122
                var primaryNamespace = relationship.PrimaryEntity.EntityNamespace;
71✔
123
                var primaryName = relationship.PrimaryEntity.EntityClass.ToSafeName();
71✔
124
                var primaryFullName = _entity.EntityNamespace != primaryNamespace
71!
125
                    ? $"{primaryNamespace}.{primaryName}"
71✔
126
                    : primaryName;
71✔
127

128
                CodeBuilder.AppendLine($"{propertyName} = new HashSet<{primaryFullName}>();");
71✔
129
            }
130
            CodeBuilder.AppendLine("#endregion");
160✔
131
        }
160✔
132

133
        CodeBuilder.AppendLine("}");
160✔
134
        CodeBuilder.AppendLine();
160✔
135
    }
160✔
136

137
    private void GenerateProperties()
138
    {
139
        CodeBuilder.AppendLine("#region Generated Properties");
160✔
140
        foreach (var property in _entity.Properties)
2,884✔
141
        {
142
            var propertyType = GetPropertyType(property);
1,282✔
143
            var propertyName = property.PropertyName.ToSafeName();
1,282✔
144

145
            if (Options.Data.Entity.Document)
1,282✔
146
            {
147
                CodeBuilder.AppendLine("/// <summary>");
1,069✔
148
                CodeBuilder.AppendLine($"/// Gets or sets the property value representing column <c>{property.ColumnName}</c>.");
1,069✔
149
                CodeBuilder.AppendLine("/// </summary>");
1,069✔
150
                CodeBuilder.AppendLine("/// <value>");
1,069✔
151
                CodeBuilder.AppendLine($"/// The property value representing column <c>{property.ColumnName}</c>.");
1,069✔
152
                CodeBuilder.AppendLine("/// </value>");
1,069✔
153
            }
154

155
            if (Options.Data.Entity.MappingAttributes)
1,282✔
156
            {
157
                if (property.IsPrimaryKey == true)
1,069✔
158
                {
159
                    CodeBuilder.AppendLine("[Key]");
140✔
160
                }
161

162
                if (property.IsConcurrencyToken == true)
1,069✔
163
                {
164
                    CodeBuilder.AppendLine("[ConcurrencyCheck]");
10✔
165
                }
166

167
                CodeBuilder.AppendLine($"[Column(\"{property.ColumnName}\", TypeName = \"{property.NativeType}\")]");
1,069✔
168

169
                if (property.IsIdentity == true)
1,069✔
170
                {
171
                    CodeBuilder.AppendLine("[DatabaseGenerated(DatabaseGeneratedOption.Identity)]");
59✔
172
                }
173
                else if (property.IsRowVersion == true || property.IsComputed == true)
1,010✔
174
                {
175
                    CodeBuilder.AppendLine("[DatabaseGenerated(DatabaseGeneratedOption.Computed)]");
28✔
176
                }
177
            }
178

179
            if (property.IsNullable == true && (property.SystemType.IsValueType || Options.Project.Nullable))
1,282✔
180
                CodeBuilder.AppendLine($"public {ToNullablePropertyType(propertyType)} {propertyName} {{ get; set; }}");
542✔
181
            else if (Options.Project.Nullable && !property.SystemType.IsValueType)
740✔
182
                CodeBuilder.AppendLine($"public {propertyType} {propertyName} {{ get; set; }} = null!;");
152✔
183
            else
184
                CodeBuilder.AppendLine($"public {propertyType} {propertyName} {{ get; set; }}");
588✔
185

186
            CodeBuilder.AppendLine();
1,282✔
187
        }
188
        CodeBuilder.AppendLine("#endregion");
160✔
189
        CodeBuilder.AppendLine();
160✔
190
    }
160✔
191

192
    private static string GetPropertyType(Property property)
193
    {
194
        return property.SystemTypeName.HasValue()
1,282!
195
            ? property.SystemTypeName
1,282✔
196
            : property.SystemType.ToType();
1,282✔
197
    }
198

199
    private static string ToNullablePropertyType(string propertyType)
200
    {
201
        return propertyType.EndsWith('?')
542!
202
            ? propertyType
542✔
203
            : propertyType + "?";
542✔
204
    }
205

206
    private void GenerateRelationshipProperties()
207
    {
208
        CodeBuilder.AppendLine("#region Generated Relationships");
160✔
209
        foreach (var relationship in _entity.Relationships.OrderBy(r => r.PropertyName))
628✔
210
        {
211
            var propertyName = relationship.PropertyName.ToSafeName();
154✔
212
            var primaryNamespace = relationship.PrimaryEntity.EntityNamespace;
154✔
213
            var primaryName = relationship.PrimaryEntity.EntityClass.ToSafeName();
154✔
214
            var primaryFullName = _entity.EntityNamespace != primaryNamespace
154!
215
                ? $"{primaryNamespace}.{primaryName}"
154✔
216
                : primaryName;
154✔
217

218
            if (relationship.Cardinality == Cardinality.Many)
154✔
219
            {
220
                if (Options.Data.Entity.Document)
71✔
221
                {
222
                    CodeBuilder.AppendLine("/// <summary>");
59✔
223
                    CodeBuilder.AppendLine($"/// Gets or sets the navigation collection for entity <see cref=\"{primaryFullName}\" />.");
59✔
224
                    CodeBuilder.AppendLine("/// </summary>");
59✔
225
                    CodeBuilder.AppendLine("/// <value>");
59✔
226
                    CodeBuilder.AppendLine($"/// The navigation collection for entity <see cref=\"{primaryFullName}\" />.");
59✔
227
                    CodeBuilder.AppendLine("/// </value>");
59✔
228
                }
229

230

231
                CodeBuilder.AppendLine($"public virtual ICollection<{primaryFullName}> {propertyName} {{ get; set; }}");
71✔
232
                CodeBuilder.AppendLine();
71✔
233
            }
234
            else
235
            {
236
                if (Options.Data.Entity.Document)
83✔
237
                {
238
                    CodeBuilder.AppendLine("/// <summary>");
67✔
239
                    CodeBuilder.AppendLine($"/// Gets or sets the navigation property for entity <see cref=\"{primaryFullName}\" />.");
67✔
240
                    CodeBuilder.AppendLine("/// </summary>");
67✔
241
                    CodeBuilder.AppendLine("/// <value>");
67✔
242
                    CodeBuilder.AppendLine($"/// The navigation property for entity <see cref=\"{primaryFullName}\" />.");
67✔
243
                    CodeBuilder.AppendLine("/// </value>");
67✔
244

245
                    foreach (var property in relationship.Properties)
274✔
246
                        CodeBuilder.AppendLine($"/// <seealso cref=\"{property.PropertyName}\" />");
70✔
247
                }
248

249
                if (!Options.Project.Nullable)
83✔
250
                    CodeBuilder.AppendLine($"public virtual {primaryFullName} {propertyName} {{ get; set; }}");
16✔
251
                else if (relationship.Cardinality == Cardinality.One)
67✔
252
                    CodeBuilder.AppendLine($"public virtual {primaryFullName} {propertyName} {{ get; set; }} = null!;");
53✔
253
                else
254
                    CodeBuilder.AppendLine($"public virtual {primaryFullName}? {propertyName} {{ get; set; }}");
14✔
255

256
                CodeBuilder.AppendLine();
83✔
257
            }
258
        }
259
        CodeBuilder.AppendLine("#endregion");
160✔
260
        CodeBuilder.AppendLine();
160✔
261
    }
160✔
262
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc