最近连续看到几篇关于把DataRow映射为实体类的Helper

http://www.cnblogs.com/inday/archive/2008/12/23/1360495.html 

http://www.cnblogs.com/yyliuliang/archive/2008/12/22/1358736.html 

但是这2个helper都有不全,就是对NullAble和Enum都支持的不好。

如:以下的测试代码,对于Nullable类型,都不能通过测试,枚举类型

比较全面DataRow的映射的helper,兼测lambda方式的快速SetValue方法(测试结果大大出乎意料)[Test]
比较全面DataRow的映射的helper,兼测lambda方式的快速SetValue方法(测试结果大大出乎意料)        
public void T3()
    }

我现在的MVC项目中的Helper也有DataRowToModel的代码,对Nullable和Enum实现了兼容。

主要代码为如下的转换代码(ps:这边分代码是更具MVC中的相关代码简化改进而来,MVC中还支持复杂类型)


        /// Converts the type of the simple.
        
/// </summary>
        
/// <param name="culture">The culture.</param>
        
/// <param name="value">The value.</param>
        
/// <param name="destinationType">Type of the destination.</param>
        
/// <returns></returns>
        public static object ConvertSimpleType(CultureInfo culture, object value, Type destinationType)
        {
            
if (value == null || destinationType.IsInstanceOfType(value))
            {
                
return value;
            }
            
if (value == DBNull.Value)
            {
                
return null;
            }
            
// if this is a user-input value but the user didn't type anything, return no value
            var valueAsString = value as string;
            
if (valueAsString != null && valueAsString.Length == 0)
            {
                
return null;
            }

            TypeConverter converter 
= TypeDescriptor.GetConverter(destinationType);
            
if (destinationType.IsGenericType && destinationType.GetGenericTypeDefinition().Equals(typeof (Nullable<>))
                
&& value.GetType() != typeof (string))
            {
                var nulla 
= new NullableConverter(destinationType);
                destinationType 
= nulla.UnderlyingType;
                
if (destinationType.IsEnum)
                {
                    
return Enum.ToObject(destinationType, value);
                }
            }

            
bool canConvertFrom = converter.CanConvertFrom(value.GetType());
            
if (!canConvertFrom)
            {
                converter 
= TypeDescriptor.GetConverter(value.GetType());
            }

            
if (!(canConvertFrom || converter.CanConvertTo(destinationType)))
            {
                
if (destinationType.IsEnum)
                {
                    
return Enum.ToObject(destinationType, value);
                }
            }

            
try
            {
                
object convertedValue = (canConvertFrom)
                                            
? converter.ConvertFrom(null, culture, value)
                                            : converter.ConvertTo(
null, culture, value, destinationType);
                
return convertedValue;
            }
            
catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                
string message = String.Format(CultureInfo.CurrentUICulture, value.GetType().FullName,
                                               destinationType.FullName);
                
throw new InvalidOperationException(message, ex);
            }
        }

 下面是测试代码

 Helper
{
    [TestFixture]
    public class Test
    {
        [Test]
        
public void T1()
        {
            var table 
= new DataTable("table");
            table.Columns.Add(
new DataColumn("s"typeof (string)));
            table.Columns.Add(
new DataColumn("e1"typeof (string)));
            table.Columns.Add(
new DataColumn("e2"typeof(string)));
            table.Columns.Add(
new DataColumn("i1"typeof (string)));
            table.Columns.Add(
new DataColumn("i2"typeof(string)));
            table.Columns.Add(
new DataColumn("b1"typeof (string)));
            table.Columns.Add(
new DataColumn("b2"typeof(string)));

            DataRow row 
= table.NewRow();
            row[
"s"= "s";
            row[
"e1"= "b";
            row[
"e2"= "c";
            row[
"i1"= "1";
            row[
"i2"= "2";
            row[
"b1"= "true";
            row[
"b2"= "true";

            var info 
= ModelHelper.DataRowToModel<Model>(row);
            Assert.IsNotNull(info);
            Assert.AreEqual(info.B1, 
true);
            Assert.AreEqual(info.B2, 
true);
            Assert.AreEqual(info.E1, E1.b);
            Assert.AreEqual(info.E2, E1.c);
            Assert.AreEqual(info.i1, 
1);
            Assert.AreEqual(info.i2, 
2);
            Assert.AreEqual(info.S, 
"s");


            row 
= table.NewRow();
            row[
"s"= "s";
            row[
"e1"= "1";
            row[
"e2"= "2";
            row[
"i1"= "1";
            row[
"i2"= "2";
            row[
"b1"= "true";
            row[
"b2"= "true";

            info 
= ModelHelper.DataRowToModel<Model>(row);
            Assert.IsNotNull(info);
            Assert.AreEqual(info.B1, 
true);
            Assert.AreEqual(info.B2, 
true);
            Assert.AreEqual(info.E1, E1.b);
            Assert.AreEqual(info.E2, E1.c);
            Assert.AreEqual(info.i1, 
1);
            Assert.AreEqual(info.i2, 
2);
            Assert.AreEqual(info.S, 
"s");
        }

        [Test]
        
public void T2()
        {
            var table 
= new DataTable("table");
            table.Columns.Add(
new DataColumn("s"typeof (string)));
            table.Columns.Add(
new DataColumn("e1"typeof (int)));
            table.Columns.Add(
new DataColumn("e2"typeof(int)));
            table.Columns.Add(
new DataColumn("i1"typeof (int)));
            table.Columns.Add(
new DataColumn("i2"typeof(int)));
            table.Columns.Add(
new DataColumn("b1"typeof (bool)));
            table.Columns.Add(
new DataColumn("b2"typeof(bool)));

            DataRow row 
= table.NewRow();
            row[
"s"= "s";
            row[
"e1"= 1;
            row[
"e2"= 2;
            row[
"i1"= 1;
            row[
"i2"= 2;
            row[
"b1"= "true";
            row[
"b2"= "true";

            var info 
= ModelHelper.DataRowToModel<Model>(row);
            Assert.IsNotNull(info);
            Assert.AreEqual(info.B1, 
true);
            Assert.AreEqual(info.E1, E1.b);
            Assert.AreEqual(info.i1, 
1);
            Assert.AreEqual(info.S, 
"s");
        }
        
        [Test]
        
public void TestPerformance()
        {
            var table 
= new DataTable("table");
            table.Columns.Add(
new DataColumn("s"typeof (string)));
            table.Columns.Add(
new DataColumn("e1"typeof (int)));
            table.Columns.Add(
new DataColumn("i1"typeof (int)));
            table.Columns.Add(
new DataColumn("b"typeof (bool)));

            DataRow row 
= table.NewRow();
            row[
"s"= "s";
            row[
"e1"= 1;
            row[
"i1"= 1;
            row[
"b"= true;

            var timer 
= new Stopwatch();
            timer.Start();
            
for (int i = 0; i < 1*10000; i++)
            {
                ModelHelper.DataRowToModel
<Model>(row);
            }
            timer.Stop();
            Console.WriteLine(timer.ElapsedMilliseconds 
+ "\t");

            var timer1 
= new Stopwatch();
            timer1.Start();
            
for (int i = 0; i < 1*10000; i++)
            {
                ModelHelper.FastDataRowToModel
<Model>(row);
            }
            timer1.Stop();
            Console.WriteLine(timer1.ElapsedMilliseconds 
+ "\t");
        }
    }

    
public class Model
    {
        
public string S { getset; }
        
public E1 E1 { getset; }
        
public E1? E2 { getset; }
        
public int i1 { getset; }
        
public int? i2 { getset; }
        
public bool B1 { getset; }
        
public bool? B2 { getset; }
    }

    
public enum E1
    {
        a,
        b,
        c
    }
}

 
前2天刚好看到”时不我待“的

自己动手写个ORM实现(4) 关于反射DataRow数据记录到实体性能的优化

写这篇文章的时候顺便做了一下测试,比较一下lambda语法和反射的语法到底是否如”时不我待“说的那样有数量级上的区别

但是测试的结果确大大出乎意料,是数量级上的区别不过是相反的,反射时间远远小于lambad语法的时间

测试1W次,反射时间:197 lambad时间:5574

下面是我的测试代码

[Test]
        public void TestPerformance()
        {
            var table 
= new DataTable("table");
            table.Columns.Add(
new DataColumn("s"typeof (string)));
            table.Columns.Add(
new DataColumn("e1"typeof (int)));
            table.Columns.Add(
new DataColumn("i1"typeof (int)));
            table.Columns.Add(
new DataColumn("b"typeof (bool)));

            DataRow row 
= table.NewRow();
            row[
"s"= "s";
            row[
"e1"= 1;
            row[
"i1"= 1;
            row[
"b"= true;

            var timer 
= new Stopwatch();
            timer.Start();
            
for (int i = 0; i < 1*10000; i++)
            {
                ModelHelper.DataRowToModel
<Model>(row);
            }
            timer.Stop();
            Console.WriteLine(timer.ElapsedMilliseconds 
+ "\t");

            var timer1 
= new Stopwatch();
            timer1.Start();
            
for (int i = 0; i < 1*10000; i++)
            {
                ModelHelper.FastDataRowToModel
<Model>(row);
            }
            timer1.Stop();
            Console.WriteLine(timer1.ElapsedMilliseconds 
+ "\t");
        }
    }

下面是sln,包含class和测试

/Files/haptear/Helper.rar 

相关文章:

  • 2021-11-20
  • 2021-05-24
  • 2022-12-23
  • 2021-12-09
  • 2022-01-24
  • 2022-12-23
  • 2022-12-23
  • 2021-06-30
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-05-01
  • 2022-02-03
  • 2022-12-23
  • 2022-12-23
  • 2022-02-19
相关资源
相似解决方案