提交 a24e15c3 编写于 作者: M mgravell

support fields when deserializing

上级 c1f70d40
......@@ -670,7 +670,7 @@ private static object GetStructDeserializer<T>(IDataReader reader)
})
.Where(info => info.Setter != null)
.ToList();
var fields = typeof(T).GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
if (length == -1)
{
length = reader.FieldCount - startBound;
......@@ -684,9 +684,11 @@ private static object GetStructDeserializer<T>(IDataReader reader)
var setters = (
from n in names
let prop = properties.FirstOrDefault(p => string.Equals(p.Name, n, StringComparison.InvariantCulture)) // case sensitive first
?? properties.FirstOrDefault(p => string.Equals(p.Name, n, StringComparison.InvariantCultureIgnoreCase)) // case insensitive second
select new { Name = n, Info = prop }
let prop = properties.FirstOrDefault(p => string.Equals(p.Name, n, StringComparison.InvariantCulture)) // property case sensitive first
?? properties.FirstOrDefault(p => string.Equals(p.Name, n, StringComparison.InvariantCultureIgnoreCase)) // property case insensitive second
let field = prop != null ? null : (fields.FirstOrDefault(p => string.Equals(p.Name, n, StringComparison.InvariantCulture)) // field case sensitive third
?? fields.FirstOrDefault(p => string.Equals(p.Name, n, StringComparison.InvariantCultureIgnoreCase))) // field case insensitive fourth
select new { Name = n, Property = prop, Field = field }
).ToList();
......@@ -703,7 +705,7 @@ private static object GetStructDeserializer<T>(IDataReader reader)
var @allDone = il.DefineLabel();
foreach (var item in setters)
{
if (item.Info != null)
if (item.Property != null || item.Field != null)
{
il.Emit(OpCodes.Dup); // stack is now [target][target]
Label isDbNullLabel = il.DefineLabel();
......@@ -720,15 +722,22 @@ private static object GetStructDeserializer<T>(IDataReader reader)
il.Emit(OpCodes.Brtrue_S, isDbNullLabel); // stack is now [target][target][value-as-object]
// unbox nullable enums as the primitive, i.e. byte etc
var nullUnderlyingType = Nullable.GetUnderlyingType(item.Info.Type);
var unboxType = nullUnderlyingType != null && nullUnderlyingType.IsEnum ? nullUnderlyingType : item.Info.Type;
Type memberType = item.Property != null ? item.Property.Type : item.Field.FieldType;
var nullUnderlyingType = Nullable.GetUnderlyingType(memberType);
var unboxType = nullUnderlyingType != null && nullUnderlyingType.IsEnum ? nullUnderlyingType : memberType;
il.Emit(OpCodes.Unbox_Any, unboxType); // stack is now [target][target][typed-value]
if (nullUnderlyingType != null && nullUnderlyingType.IsEnum)
{
il.Emit(OpCodes.Newobj, item.Info.Type.GetConstructor(new[] { nullUnderlyingType }));
il.Emit(OpCodes.Newobj, memberType.GetConstructor(new[] { nullUnderlyingType }));
}
if (item.Property != null)
{
il.Emit(OpCodes.Callvirt, item.Property.Setter); // stack is now [target]
}
else
{
il.Emit(OpCodes.Stfld, item.Field); // stack is now [target]
}
il.Emit(OpCodes.Callvirt, item.Info.Setter); // stack is now [target]
il.Emit(OpCodes.Br_S, finishLabel); // stack is now [target]
il.MarkLabel(isDbNullLabel); // incoming stack: [target][target][value]
......
......@@ -322,6 +322,36 @@ public void TestMultiMapDynamic()
connection.Execute("drop table #Users drop table #Posts");
}
public void TestFieldsAndPrivates()
{
var data = connection.Query<TestFieldCaseAndPrivatesEntity>(
@"select a=1,b=2,c=3,d=4,f='5'").Single();
data.a.IsEqualTo(1);
data.GetB().IsEqualTo(2);
data.c.IsEqualTo(3);
data.GetD().IsEqualTo(4);
data.e.IsEqualTo(5);
}
private class TestFieldCaseAndPrivatesEntity
{
public int a { get; set; }
private int b { get; set; }
public int GetB() { return b; }
public int c = 0;
private int d = 0;
public int GetD() { return d; }
public int e { get; set; }
private string f
{
get { return e.ToString(); }
set { e = int.Parse(value); }
}
}
public void TestMultiReaderBasic()
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册