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

loresoft / EntityFrameworkCore.Generator / 27760980405

18 Jun 2026 12:56PM UTC coverage: 75.418% (+0.7%) from 74.693%
27760980405

push

github

pwelter34
fix build

1007 of 1723 branches covered (58.44%)

Branch coverage included in aggregate %.

4221 of 5209 relevant lines covered (81.03%)

1242.99 hits per line

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

91.88
/src/EntityFrameworkCore.Generator.Core/Templates/MapperClassTemplate.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 MapperClassTemplate : CodeTemplateBase
8
{
9
    private readonly Entity _entity;
10

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

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

20
        if (Options.Model.Mapper.Header.HasValue())
138!
21
            CodeBuilder.AppendLine(Options.Model.Mapper.Header).AppendLine();
×
22

23
        CodeBuilder.AppendLine("using System;");
138✔
24
        CodeBuilder.AppendLine();
138✔
25
        CodeBuilder.AppendLine("using AutoMapper;");
138✔
26
        CodeBuilder.AppendLine();
138✔
27

28
        var imports = new SortedSet<string>
138✔
29
        {
138✔
30
            _entity.EntityNamespace
138✔
31
        };
138✔
32

33
        foreach (var model in _entity.Models)
1,066✔
34
            imports.Add(model.ModelNamespace);
395✔
35

36
        foreach (var import in imports)
828✔
37
        {
38
            if (_entity.MapperNamespace != import)
276✔
39
                CodeBuilder.AppendLine($"using {import};");
276✔
40
        }
41

42
        CodeBuilder.AppendLine();
138✔
43

44
        CodeBuilder.Append($"namespace {_entity.MapperNamespace}");
138✔
45

46
        if (Options.Project.FileScopedNamespace)
138✔
47
        {
48
            CodeBuilder.AppendLine(";");
137✔
49
            CodeBuilder.AppendLine();
137✔
50
            GenerateClass();
137✔
51
        }
52
        else
53
        {
54
            CodeBuilder.AppendLine();
1✔
55
            CodeBuilder.AppendLine("{");
1✔
56

57
            using (CodeBuilder.Indent())
1✔
58
            {
59
                GenerateClass();
1✔
60
            }
1✔
61

62
            CodeBuilder.AppendLine("}");
1✔
63
        }
64

65
        return CodeBuilder.ToString();
138✔
66
    }
67

68
    private void GenerateClass()
69
    {
70
        var entityClass = _entity.EntityClass.ToSafeName();
138✔
71
        var entityFullName = $"{_entity.EntityNamespace}.{entityClass}";
138✔
72
        var mapperClass = _entity.MapperClass.ToSafeName();
138✔
73

74
        if (Options.Model.Mapper.Document)
138!
75
        {
76
            GenerateClassDocumentation(entityFullName);
138✔
77
        }
78
        if (Options.Model.Mapper.Attributes.HasValue())
138!
79
        {
80
            CodeBuilder.AppendLine(Options.Model.Mapper.Attributes);
×
81
        }
82
        CodeBuilder.AppendLine($"public partial class {mapperClass}");
138✔
83

84
        if (_entity.MapperBaseClass.HasValue())
138✔
85
        {
86
            var mapperBaseClass = _entity.MapperBaseClass.ToSafeName();
137✔
87
            using (CodeBuilder.Indent())
137✔
88
                CodeBuilder.AppendLine($": {mapperBaseClass}");
137✔
89
        }
90

91
        CodeBuilder.AppendLine("{");
138✔
92

93
        using (CodeBuilder.Indent())
138✔
94
        {
95
            GenerateConstructor();
138✔
96
        }
138✔
97

98
        CodeBuilder.AppendLine("}");
138✔
99
    }
138✔
100

101
    private void GenerateConstructor()
102
    {
103
        var mapperClass = _entity.MapperClass.ToSafeName();
138✔
104
        var mapperFullName = $"{_entity.MapperNamespace}.{mapperClass}";
138✔
105

106
        var entityClass = _entity.EntityClass.ToSafeName();
138✔
107
        var entityFullName = $"{_entity.EntityNamespace}.{entityClass}";
138✔
108

109
        if (Options.Model.Mapper.Document)
138!
110
        {
111
            GenerateConstructorDocumentation(mapperFullName, entityFullName);
138✔
112
        }
113

114
        CodeBuilder.AppendLine($"public {mapperClass}()");
138✔
115
        CodeBuilder.AppendLine("{");
138✔
116

117
        string? readFullName = null;
138✔
118
        string? updateFullName = null;
138✔
119

120
        using (CodeBuilder.Indent())
138✔
121
        {
122
            foreach (var model in _entity.Models)
1,066✔
123
            {
124
                var modelClass = model.ModelClass.ToSafeName();
395✔
125
                var modelFullName = $"{model.ModelNamespace}.{modelClass}";
395✔
126

127
                switch (model.ModelType)
395✔
128
                {
129
                    case ModelType.Read:
130
                        readFullName = modelFullName;
138✔
131
                        CodeBuilder.AppendLine($"CreateMap<{entityFullName}, {modelFullName}>();").AppendLine();
138✔
132
                        break;
138✔
133
                    case ModelType.Create:
134
                        CodeBuilder.AppendLine($"CreateMap<{modelFullName}, {entityFullName}>();").AppendLine();
128✔
135
                        CodeBuilder.AppendLine($"CreateMap<{entityFullName}, {modelFullName}>();").AppendLine();
128✔
136
                        break;
128✔
137
                    case ModelType.Update:
138
                        updateFullName = modelFullName;
129✔
139
                        CodeBuilder.AppendLine($"CreateMap<{entityFullName}, {modelFullName}>();").AppendLine();
129✔
140
                        CodeBuilder.AppendLine($"CreateMap<{modelFullName}, {entityFullName}>();").AppendLine();
129✔
141
                        break;
142
                }
143
            }
144

145
            // include support for coping read model to update model
146
            if (readFullName.HasValue() && updateFullName.HasValue())
138✔
147
                CodeBuilder.AppendLine($"CreateMap<{readFullName}, {updateFullName}>();").AppendLine();
129✔
148

149
        }
138✔
150

151
        CodeBuilder.AppendLine("}");
138✔
152
        CodeBuilder.AppendLine();
138✔
153
    }
138✔
154

155
    private void GenerateClassDocumentation(string entityClass)
156
    {
157
        var sourceName = ToXmlText(GetQualifiedTableName());
138✔
158
        var sourceType = _entity.IsView ? "view" : "table";
138✔
159
        var modelDescription = GetModelDescription();
138✔
160

161
        CodeBuilder.AppendLine("/// <summary>");
138✔
162

163
        if (sourceName.HasValue())
138!
164
            CodeBuilder.AppendLine($"/// Configures AutoMapper mappings for the <see cref=\"{entityClass}\" /> entity mapped to the <c>{sourceName}</c> {sourceType}{modelDescription}.");
138✔
165
        else
166
            CodeBuilder.AppendLine($"/// Configures AutoMapper mappings for the <see cref=\"{entityClass}\" /> entity{modelDescription}.");
×
167

168
        CodeBuilder.AppendLine("/// </summary>");
138✔
169
    }
138✔
170

171
    private void GenerateConstructorDocumentation(string mapperClass, string entityClass)
172
    {
173
        CodeBuilder.AppendLine("/// <summary>");
138✔
174
        CodeBuilder.AppendLine($"/// Initializes a new instance of the <see cref=\"{mapperClass}\"/> class and creates mappings for <see cref=\"{entityClass}\" />.");
138✔
175
        CodeBuilder.AppendLine("/// </summary>");
138✔
176
    }
138✔
177

178
    private string GetModelDescription()
179
    {
180
        var modelTypes = _entity.Models
138✔
181
            .Select(model => model.ModelType switch
138✔
182
            {
138✔
183
                ModelType.Create => "create",
138✔
184
                ModelType.Update => "update",
138✔
185
                _ => "read"
138✔
186
            })
138✔
187
            .Distinct(StringComparer.Ordinal)
138✔
188
            .OrderBy(value => value, StringComparer.Ordinal)
138✔
189
            .ToList();
138✔
190

191
        return modelTypes.Count == 0
138!
192
            ? string.Empty
138✔
193
            : $" and its generated {FormatList(modelTypes)} models";
138✔
194
    }
195

196
    private static string FormatList(IReadOnlyList<string> values)
197
    {
198
        return values.Count switch
138!
199
        {
138✔
200
            0 => string.Empty,
×
201
            1 => values[0],
9✔
202
            2 => $"{values[0]} and {values[1]}",
1✔
203
            _ => $"{string.Join(", ", values.Take(values.Count - 1))}, and {values[^1]}"
128✔
204
        };
138✔
205
    }
206

207
    private string? GetQualifiedTableName()
208
    {
209
        if (_entity.TableName.IsNullOrEmpty())
138!
210
            return _entity.TableName;
×
211

212
        return _entity.TableSchema.HasValue()
138✔
213
            ? $"{_entity.TableSchema}.{_entity.TableName}"
138✔
214
            : _entity.TableName;
138✔
215
    }
216

217
}
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