Skip to content

Commit ce149b4

Browse files
committed
Added ToCLASSNAMEFirstOrDefault method generation. Fixed some minor test warnings
1 parent 84ce89c commit ce149b4

3 files changed

Lines changed: 75 additions & 12 deletions

File tree

MapDataReader.Tests/TestActualCode.cs

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,14 @@ public class MyObject
3838

3939
public MyEnum Dude { get; set; }
4040
public MyEnum? NullableDude { get; set; }
41-
public string Name { get; set; }
41+
public string? Name { get; set; }
4242

4343
public int GetOnly { get; } = 123; //property without public setter!
4444

45-
public byte[] ByeArray { get; set; }
46-
public int[] IntArray { get; set; }
47-
public string[] StringArray { get; set; }
48-
public long[] LongArray { get; set; }
45+
public byte[]? ByeArray { get; set; }
46+
public int[]? IntArray { get; set; }
47+
public string[]? StringArray { get; set; }
48+
public long[]? LongArray { get; set; }
4949
}
5050

5151
[TestClass]
@@ -205,6 +205,38 @@ public void TestDatatReader()
205205
Assert.IsTrue(list[0].LaBoolissimmo == true);
206206
}
207207

208+
[TestMethod]
209+
public void TestDataReaderFirstOrDefault()
210+
{
211+
var dt = new DataTable();
212+
dt.Columns.AddRange(new[] {
213+
new DataColumn("ID", typeof(int)),
214+
new DataColumn("Name", typeof(string)),
215+
});
216+
dt.Rows.Add(123, "first");
217+
dt.Rows.Add(456, "second");
218+
219+
var result = dt.CreateDataReader().ToMyObjectFirstOrDefault();
220+
221+
Assert.IsNotNull(result);
222+
Assert.IsTrue(result.Id == 123);
223+
Assert.IsTrue(result.Name == "first");
224+
}
225+
226+
[TestMethod]
227+
public void TestDataReaderFirstOrDefault_Empty()
228+
{
229+
var dt = new DataTable();
230+
dt.Columns.AddRange(new[] {
231+
new DataColumn("ID", typeof(int)),
232+
new DataColumn("Name", typeof(string)),
233+
});
234+
235+
var result = dt.CreateDataReader().ToMyObjectFirstOrDefault();
236+
237+
Assert.IsNull(result);
238+
}
239+
208240
[TestMethod]
209241
public void TestBaseClassAssign()
210242
{
@@ -237,7 +269,7 @@ public class BaseClass
237269
[GenerateDataReaderMapper]
238270
public class ChildClass : BaseClass
239271
{
240-
public string Name { get; set; }
272+
public string? Name { get; set; }
241273
}
242274
}
243275

MapDataReader.Tests/TestGenerator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ private static Compilation CreateCompilation(string source)
7878
MetadataReference.CreateFromFile(typeof(MapperGenerator).GetTypeInfo().Assembly.Location),
7979
MetadataReference.CreateFromFile(typeof(IDataReader).GetTypeInfo().Assembly.Location),
8080
MetadataReference.CreateFromFile(typeof(Enumerable).GetTypeInfo().Assembly.Location),
81-
MetadataReference.CreateFromFile(Path.Combine(Path.GetDirectoryName(typeof(object).Assembly.Location), "System.Runtime.dll")),
81+
MetadataReference.CreateFromFile(Path.Combine(Path.GetDirectoryName(typeof(object).Assembly.Location)!, "System.Runtime.dll")),
8282
MetadataReference.CreateFromFile(AppDomain.CurrentDomain.GetAssemblies().Single(a => a.GetName().Name == "netstandard").Location)
8383
},
8484
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

MapDataReader/MapperGenerator.cs

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,29 @@
33
using Microsoft.CodeAnalysis.CSharp.Syntax;
44
using System;
55
using System.Collections.Generic;
6-
using System.Collections.Immutable;
76
using System.Linq;
87

98
namespace MapDataReader
109
{
10+
/// <summary>
11+
/// Mark a class with this attribute to generate a data reader mapper for it.
12+
/// </summary>
1113
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
1214
public class GenerateDataReaderMapperAttribute : Attribute
1315
{
1416
}
1517

18+
public static class DataReaderHelper
19+
{
20+
public static string[] GetUpperColumnNames(System.Data.IDataReader dr)
21+
{
22+
string[] columnNames = new string[dr.FieldCount];
23+
for (int i = 0; i < columnNames.Length; i++)
24+
columnNames[i] = dr.GetName(i).ToUpperInvariant();
25+
return columnNames;
26+
}
27+
}
28+
1629
[Generator]
1730
public class MapperGenerator : ISourceGenerator
1831
{
@@ -86,10 +99,7 @@ private static void SetPropertyByUpperName(this {typeNodeSymbol.FullName()} targ
8699
87100
if (dr.Read())
88101
{{
89-
string[] columnNames = new string[dr.FieldCount];
90-
91-
for (int i = 0; i < columnNames.Length; i++)
92-
columnNames[i] = dr.GetName(i).ToUpperInvariant();
102+
string[] columnNames = DataReaderHelper.GetUpperColumnNames(dr);
93103
94104
do
95105
{{
@@ -105,6 +115,27 @@ private static void SetPropertyByUpperName(this {typeNodeSymbol.FullName()} targ
105115
}}
106116
dr.Close();
107117
return list;
118+
}}
119+
120+
public static {typeNodeSymbol.FullName()} To{typeNode.Identifier}FirstOrDefault(this IDataReader dr)
121+
{{
122+
if (!dr.Read())
123+
{{
124+
dr.Close();
125+
return default;
126+
}}
127+
128+
string[] columnNames = DataReaderHelper.GetUpperColumnNames(dr);
129+
130+
var result = new {typeNodeSymbol.FullName()}();
131+
for (int i = 0; i < columnNames.Length; i++)
132+
{{
133+
var value = dr[i];
134+
if (value is DBNull) value = null;
135+
SetPropertyByUpperName(result, columnNames[i], value);
136+
}}
137+
dr.Close();
138+
return result;
108139
}}";
109140
}
110141

0 commit comments

Comments
 (0)