using System.Collections.Generic; using System.Linq; using Xunit; namespace Dapper.Tests { public partial class DataReaderTests : TestBase { [Fact] public void GetSameReaderForSameShape() { var origReader = connection.ExecuteReader("select 'abc' as Name, 123 as Id"); var origParser = origReader.GetRowParser(typeof(HazNameId)); var typedParser = origReader.GetRowParser(); ReferenceEquals(origParser, typedParser).IsEqualTo(true); var list = origReader.Parse().ToList(); list.Count.IsEqualTo(1); list[0].Name.IsEqualTo("abc"); list[0].Id.IsEqualTo(123); origReader.Dispose(); var secondReader = connection.ExecuteReader("select 'abc' as Name, 123 as Id"); var secondParser = secondReader.GetRowParser(typeof(HazNameId)); var thirdParser = secondReader.GetRowParser(typeof(HazNameId), 1); list = secondReader.Parse().ToList(); list.Count.IsEqualTo(1); list[0].Name.IsEqualTo("abc"); list[0].Id.IsEqualTo(123); secondReader.Dispose(); // now: should be different readers, but same parser ReferenceEquals(origReader, secondReader).IsEqualTo(false); ReferenceEquals(origParser, secondParser).IsEqualTo(true); ReferenceEquals(secondParser, thirdParser).IsEqualTo(false); } [Fact] public void DiscriminatedUnion() { List result = new List(); using (var reader = connection.ExecuteReader(@" select 'abc' as Name, 1 as Type, 3.0 as Value union all select 'def' as Name, 2 as Type, 4.0 as Value")) { if (reader.Read()) { var toFoo = reader.GetRowParser(typeof(Discriminated_Foo)); var toBar = reader.GetRowParser(typeof(Discriminated_Bar)); var col = reader.GetOrdinal("Type"); do { switch (reader.GetInt32(col)) { case 1: result.Add(toFoo(reader)); break; case 2: result.Add(toBar(reader)); break; } } while (reader.Read()); } } result.Count.IsEqualTo(2); result[0].Type.IsEqualTo(1); result[1].Type.IsEqualTo(2); var foo = (Discriminated_Foo)result[0]; foo.Name.IsEqualTo("abc"); var bar = (Discriminated_Bar)result[1]; bar.Value.IsEqualTo((float)4.0); } [Fact] public void DiscriminatedUnionWithMultiMapping() { var result = new List(); using (var reader = connection.ExecuteReader(@" select 'abc' as Name, 1 as Type, 3.0 as Value, 1 as Id, 'zxc' as Name union all select 'def' as Name, 2 as Type, 4.0 as Value, 2 as Id, 'qwe' as Name")) { if (reader.Read()) { var col = reader.GetOrdinal("Type"); var splitOn = reader.GetOrdinal("Id"); var toFoo = reader.GetRowParser(typeof(DiscriminatedWithMultiMapping_Foo),0, splitOn); var toBar = reader.GetRowParser(typeof(DiscriminatedWithMultiMapping_Bar),0, splitOn); var toHaz = reader.GetRowParser(typeof(HazNameId),splitOn, reader.FieldCount - splitOn); do { DiscriminatedWithMultiMapping_BaseType obj = null; switch (reader.GetInt32(col)) { case 1: obj = toFoo(reader); break; case 2: obj = toBar(reader); break; } obj.IsNotNull(); obj.HazNameIdObject = toHaz(reader); result.Add(obj); } while (reader.Read()); } } result.Count.IsEqualTo(2); result[0].Type.IsEqualTo(1); result[1].Type.IsEqualTo(2); var foo = (DiscriminatedWithMultiMapping_Foo)result[0]; foo.Name.IsEqualTo("abc"); foo.HazNameIdObject.Id.IsEqualTo(1); foo.HazNameIdObject.Name.IsEqualTo("zxc"); var bar = (DiscriminatedWithMultiMapping_Bar)result[1]; bar.Value.IsEqualTo((float)4.0); bar.HazNameIdObject.Id.IsEqualTo(2); bar.HazNameIdObject.Name.IsEqualTo("qwe"); } private abstract class Discriminated_BaseType { public abstract int Type { get; } } private class Discriminated_Foo : Discriminated_BaseType { public string Name { get; set; } public override int Type { get { return 1; } } } private class Discriminated_Bar : Discriminated_BaseType { public float Value { get; set; } public override int Type { get { return 2; } } } private abstract class DiscriminatedWithMultiMapping_BaseType : Discriminated_BaseType { public abstract HazNameId HazNameIdObject { get; set; } } private class DiscriminatedWithMultiMapping_Foo : DiscriminatedWithMultiMapping_BaseType { public override HazNameId HazNameIdObject { get; set; } public string Name { get; set; } public override int Type { get { return 1; } } } private class DiscriminatedWithMultiMapping_Bar : DiscriminatedWithMultiMapping_BaseType { public override HazNameId HazNameIdObject { get; set; } public float Value { get; set; } public override int Type { get { return 2; } } } } }