Repository navigation
Expand file tree
/
Copy pathDataReaderExtensions.cs
More file actions
143 lines (120 loc) · 4.79 KB
/
Copy pathDataReaderExtensions.cs
File metadata and controls
143 lines (120 loc) · 4.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
//Contributor: Rick Strahl - http://codepaste.net/qqcf4x
using System;
using System.Collections.Generic;
using System.Data;
using System.Dynamic;
using System.Linq;
using SmartStore.ComponentModel;
namespace SmartStore.Data
{
public static class DataReaderExtensions
{
public static object GetValue(this IDataReader reader, string columnName)
{
try
{
if (reader != null && !reader.IsClosed && columnName.HasValue())
{
int ordinal = reader.GetOrdinal(columnName);
return reader.GetValue(ordinal);
}
}
catch (Exception ex)
{
ex.Dump();
}
return null;
}
public static IEnumerable<T> MapSequence<T>(this IDataReader reader, params string[] fieldsToSkip)
where T : new()
{
Guard.NotNull(reader, nameof(reader));
while (reader.Read())
{
yield return reader.Map<T>(fieldsToSkip);
}
}
public static IEnumerable<dynamic> MapSequence(this IDataReader reader, params string[] fieldsToSkip)
{
Guard.NotNull(reader, nameof(reader));
while (reader.Read())
{
yield return reader.Map(fieldsToSkip);
}
}
/// <summary>
/// Populates an object from a single DataReader row using
/// fast reflection routines by matching the DataReader fields to a public property on
/// the object passed in. Unmatched properties are left unchanged.
///
/// You need to pass in a data reader located on the active row you want
/// to serialize.
/// </summary>
/// <param name="reader">Instance of the DataReader to read data from. Should be located on the correct record (Read() should have been called on it before calling this method)</param>
/// <param name="fieldsToSkip">An array of reader field names to ignore</param>
public static T Map<T>(this IDataReader reader, params string[] fieldsToSkip)
where T : new()
{
if (reader.IsClosed)
throw new InvalidOperationException("Data reader cannot be used because it's already closed");
var instance = new T();
MapObject(reader, instance, fieldsToSkip);
return instance;
}
public static dynamic Map(this IDataReader reader, params string[] fieldsToSkip)
{
if (reader.IsClosed)
throw new InvalidOperationException("Data reader cannot be used because it's already closed");
dynamic instance = new ExpandoObject();
MapDictionary(reader, instance, fieldsToSkip);
return instance;
}
public static void Map(this IDataReader reader, object instance, params string[] fieldsToSkip)
{
Guard.NotNull(instance, "instance");
if (reader.IsClosed)
throw new InvalidOperationException("Data reader cannot be used because it's already closed");
var dict = instance as IDictionary<string, object>;
if (dict != null)
{
MapDictionary(reader, dict, fieldsToSkip);
}
else
{
MapObject(reader, instance, fieldsToSkip);
}
}
private static void MapObject(IDataReader reader, object instance, params string[] fieldsToSkip)
{
var fastProperties = FastProperty.GetProperties(instance.GetType());
if (fastProperties.Count == 0)
return;
for (int i = 0; i < reader.FieldCount; i++)
{
string name = reader.GetName(i);
if (fastProperties.ContainsKey(name))
{
var fastProp = fastProperties[name];
if (fieldsToSkip.Contains(name))
continue;
if ((fastProp != null) && fastProp.Property.CanWrite)
{
var dbValue = reader.GetValue(i);
fastProp.SetValue(instance, (dbValue == DBNull.Value) ? null : dbValue);
}
}
}
}
private static void MapDictionary(IDataReader reader, IDictionary<string, object> instance, params string[] fieldsToSkip)
{
for (int i = 0; i < reader.FieldCount; i++)
{
string name = reader.GetName(i);
if (fieldsToSkip.Contains(name))
continue;
var dbValue = reader.GetValue(i);
instance[name] = (dbValue == DBNull.Value) ? null : dbValue;
}
}
}
}