OO Mapper 实践(下篇)
上篇介绍了OO Mapper 最核心的映射,简单类型映射,这篇将介绍的复合类型的映射。
1. Dictionary - > Dictionary 字典类型分为:IDictionary,IDictioanry<TKey,TValue>
public class SourceValue { public int Value { get; set; } } public class DestValue { public int Value { get; set; } } [Test] public void Example() { var sourceDict = new Dictionary<string, SourceValue> { {"First", new SourceValue {Value = 5}}, {"Second", new SourceValue {Value = 10}}, {"Third", new SourceValue {Value = 15}} }; var destDict = Mapper.Map<Dictionary<string, SourceValue>, IDictionary<string, DestValue>>(sourceDict); Assert.AreEqual(3, destDict.Count); Assert.AreEqual(destDict["First"].Value, 5); Assert.AreEqual(destDict["Second"].Value, 10); Assert.AreEqual(destDict["Third"].Value, 15); } [Test] public void Example2() { var sourceDict = new Dictionary<int, SourceValue> { {1, new SourceValue {Value = 5}}, {2, new SourceValue {Value = 10}}, {3, new SourceValue {Value = 15}} }; var destDict = Mapper.Map<Dictionary<int, SourceValue>, IDictionary<string, DestValue>>(sourceDict); Assert.AreEqual(3, destDict.Count); Assert.AreEqual(destDict["1"].Value, 5); Assert.AreEqual(destDict["2"].Value, 10); Assert.AreEqual(destDict["3"].Value, 15); } enum sourceKey { First, Second, Third, } enum destKey { First, Second, Third, } public void Example3() { var sourceDict = new Dictionary<sourceKey, SourceValue> { {sourceKey.First, new SourceValue {Value = 5}}, {sourceKey.Second, new SourceValue {Value = 10}}, {sourceKey.Third, new SourceValue {Value = 15}} }; var destDict = Mapper.Map<Dictionary<sourceKey, SourceValue>, IDictionary<destKey, DestValue>>(sourceDict); Assert.AreEqual(3, destDict.Count); Assert.AreEqual(destDict[destKey.First].Value, 5); Assert.AreEqual(destDict[destKey.Second].Value, 10); Assert.AreEqual(destDict[destKey.Third].Value, 15); } public void Example4() { var sourceDict = new Hashtable() { {1, new SourceValue {Value = 5}}, {2, new SourceValue {Value = 10}}, {3, new SourceValue {Value = 15}} }; var destDict = Mapper.Map<Hashtable, IDictionary<string, DestValue>>(sourceDict); Assert.AreEqual(3, destDict.Count); Assert.AreEqual(destDict["1"].Value, 5); Assert.AreEqual(destDict["2"].Value, 10); Assert.AreEqual(destDict["3"].Value, 15); } public void Example5() { var sourceDict = new Dictionary<int, SourceValue>() { {1, new SourceValue {Value = 5}}, {2, new SourceValue {Value = 10}}, {3, new SourceValue {Value = 15}} }; var destDict = Mapper.Map<Dictionary<int, SourceValue>, Hashtable>(sourceDict); Assert.AreEqual(3, destDict.Count); Assert.AreEqual((destDict[1] as SourceValue).Value, 5); Assert.AreEqual((destDict[2] as SourceValue).Value, 10); Assert.AreEqual((destDict[3] as SourceValue).Value, 15); }
2. Class -> Dictionary
public class Person1 { public string Name { get; set; } public int Age { get; set; } public bool Sex { get; set; } } [Test] public void SimpleTest() { var source = new Person1 { Name = "Kevin", Age = 30, Sex = true }; var dst = Mapper.Map<Person1, IDictionary<string, object>>(source); Assert.AreEqual(dst["Name"], source.Name); Assert.AreEqual(dst["Age"], source.Age); Assert.AreEqual(dst["Sex"], source.Sex); } [Test] public void IgnoreMemberTest() { var source = new Person1 { Name = "Kevin", Age = 30, Sex = true }; var dst = Mapper .CreateMapper<Person1, IDictionary<string, object>>() .IgnoreSourceMember(x => x.Sex) .Map(source); Assert.AreEqual(dst["Name"], source.Name); Assert.AreEqual(dst["Age"], source.Age); Assert.IsFalse(dst.ContainsKey("Sex")); }
3. Dictionary -> Class 简单转换
public class TeamSearchCondition { public string BusinessCategory; public string NIROI; public string Lob; [Splite(',')] public int[] Product; public string FormName; } [Test] public void Test() { var source = new Dictionary<string, string>(); source["BusinessCategory"] = "kevin"; source["NIROI"] = "30"; source["Lob"] = "true"; source["Product"] = "1,2"; source["FormName"] = "true"; var dst = Mapper.Map<IDictionary<string, string>, TeamSearchCondition>(source); Assert.IsNotNull(dst); Assert.IsNotNull(dst.Product != null); Assert.AreEqual(2, dst.Product.Length); Assert.AreEqual(1, dst.Product[0]); Assert.AreEqual(2, dst.Product[1]); }
4. Dictioanry -> Class 复杂一点的转换
public class Book { public int BookId { get; set; } public string BookName { get; set; } public Author Author { get; set; } public DateTime PublishedDate { get; set; } } public class Author { public int AuthorId { get; set; } public string AuthorName { get; set; } public string Nation { get; set; } } [Test] public void TestSubProperty() { var sourceDict = new Dictionary<string, string> { {"BookName", "设计模式"}, {"Author.AuthorName", "四人帮"}, {"Author.AuthorId", "3"} }; var destDict = Mapper.Map<Dictionary<string, string>, Book>(sourceDict); Assert.NotNull(destDict); Assert.AreEqual("设计模式", destDict.BookName); Assert.AreEqual("四人帮", destDict.Author.AuthorName); Assert.AreEqual(3, destDict.Author.AuthorId); }
5. DataReader -> List
public enum TestClassStatus { First = 0, Second = 1 } class TestClass { public int Id { get; set; } public string Name; public TestClassStatus? Status; public Guid Guid; } [Test] public void Test() { var dt = new DataTable(); dt.Columns.Add(new DataColumn("Id", typeof(long))); dt.Columns.Add(new DataColumn("Name", typeof(string))); dt.Columns[1].AllowDBNull = true; dt.Columns.Add(new DataColumn("Status", typeof(long))); dt.Columns.Add(new DataColumn("Guid", typeof(Guid))); int count = 5; for (int i = 0; i < count; ++i) { if(i%2 == 0) dt.Rows.Add(i, Guid.NewGuid().ToString(), DBNull.Value, Guid.NewGuid()); else dt.Rows.Add(i, DBNull.Value, 1, Guid.NewGuid()); } var reader = dt.CreateDataReader(); var items = Mapper.Map<IDataReader, IEnumerable<TestClass>>(reader); Assert.AreEqual(count, items.Count()); foreach(DataRow row in dt.Rows) { var o1 = row[0]; var o2 = row[1]; var o3 = row[2]; var o4 = row[3]; var i1 = Mapper.Map<object,int>(o1); var i2 = Mapper.Map<object,string>(o2); var i3 = Mapper.Map<object,int>(o3); var i4 = Mapper.Map<object,Guid>(o4); } }
6. DataTable -> List (原理是先把DataTable->DataReader->List)
7. List -> DataTable (略)
8. ListSource -> List , List -> ListSource (略)
9. List -> List
enum MappingFromStatus { Value1 = 0, Value2 = 1 } class MappingFrom { public int FromID { get; set; } public string Name; public int Other; public MappingFromStatus Status; public Guid Guid; } struct MappingTo { public int From_id; public string Name { get; set; } public string Other2; public int Status; public Guid Guid; } [Test] public void Test() { var actual = Mapper.Map<string, int>("12"); Assert.AreEqual(12, actual); Assert.AreEqual(1, Mapper.Map<int, decimal?>(1)); var actualArray = Mapper.Map<IList<int>, decimal?[]>(new List<int> { 1, 2, 3 }); Assert.AreEqual(2, actualArray[1]); var longColl = Mapper.Map<int[], List<long>>(new int[] { 1, 2, 3 }); Assert.AreEqual(2, longColl[1]); var doubleArray = Mapper.Map<List<string>, double[]>(new List<string> { "1.1", "2.2", "3.3" }); Assert.AreEqual(2.2, doubleArray[1]); Mapper .CreateMapper<MappingFrom, MappingTo>() .IgnoreCase(true) .IgnoreUnderscore(true) .IgnoreSourceMember(x => x.Guid); var guid = Guid.NewGuid(); var customFrom = new MappingFrom { FromID = 1, Name = "name", Status = MappingFromStatus.Value2, Guid = guid }; var customTo = Mapper.Map<MappingFrom, MappingTo>(customFrom); Assert.AreEqual(1, customTo.From_id); Assert.AreEqual("name", customTo.Name); Assert.IsNullOrEmpty(customTo.Other2); Assert.AreEqual(1, customTo.Status); Assert.AreNotEqual(guid, customTo.Guid);
10. Class -> Class
public class ModelObject { public DateTime BaseDate { get; set; } public ModelSubObject Sub { get; set; } public ModelSubObject Sub2 { get; set; } public ModelSubObject SubWithExtraName { get; set; } } public class ModelSubObject { public string ProperName { get; set; } public ModelSubSubObject SubSub { get; set; } } public class ModelSubSubObject { public string IAmACoolProperty { get; set; } } public class ModelDto { public DateTime BaseDate { get; set; } public string SubProperName { get; set; } public string Sub2ProperName { get; set; } public string SubWithExtraNameProperName { get; set; } public string SubSubSubIAmACoolProperty { get; set; } } [Test] public void TestFlattering() { var source = new ModelObject { BaseDate = DateTime.Now, Sub = new ModelSubObject { ProperName = "Some name", SubSub = new ModelSubSubObject { IAmACoolProperty = "Cool daddy-o" } }, Sub2 = new ModelSubObject { ProperName = "Sub 2 name" }, SubWithExtraName = new ModelSubObject { ProperName = "Some other name" }, }; var b =Mapper.Map<ModelObject, ModelDto>(source); Assert.AreEqual(source.BaseDate, b.BaseDate); Assert.AreEqual(source.Sub.ProperName, b.SubProperName); Assert.AreEqual(source.Sub2.ProperName, b.Sub2ProperName); Assert.AreEqual(source.SubWithExtraName.ProperName, b.SubWithExtraNameProperName); Assert.AreEqual(source.Sub.SubSub.IAmACoolProperty, b.SubSubSubIAmACoolProperty); }
完。