A:DataReader 直接绑定,B: DataReader直接转换成EntityCollection,C:用Reflection将DataReader转换成EntityCollection,三种方式到底速度差多少?
用2000笔数据作试验。测试下来,直接转换成EntityCollection所化的时间与直接绑定相差无几,大概是1~1.5倍,用Reflection将DataReader转换成EntityCollection所化时间是直接绑定的4~5倍左右,用注释起来的代码的话花的时间就多了,大概8倍的样子。
但是转化成EntityCollection,还要写代码来处理排序。
直接绑定大致如此
private void BindByDirect(SqlDataReader dr)
{
contactData.DataSource= dr;
contactData.DataBind();
}
用EntityCollection
private void BindByEntityCollection(SqlDataReader dr)
{
ContactCollection contacts = new ContactCollection();
while(dr.Read())
{
Contact contact = new Contact();
contact.Contact_ID = dr["Contact_ID"].ToString();
contact.Contact_LastName = dr["Contact_LastName"].ToString() ;
contact.Contact_JobTitle = dr["Contact_JobTitle"].ToString();
contact.Contact_Department = dr["Contact_Department"].ToString();
contact.Contact_Rank = dr["Contact_Rank"].ToString();
contacts.Add(contact);
}
contactData.DataSource= contacts;
contactData.DataBind();
}
借助反射
private void BindByReflection(SqlDataReader dr)
{
ContactCollection contacts = new ContactCollection();
Type objType = typeof(Contact);
PropertyInfo[] properties = objType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
Type fieldAttributeType = typeof(FieldAttribute);
while(dr.Read())
{
//Contact contact = new Contact();
//foreach (PropertyInfo property in properties)
//{
// FieldAttribute fieldAttribute = (FieldAttribute) Attribute.GetCustomAttribute(
// property, fieldAttributeType);
// property.SetValue(contact,dr[fieldAttribute.ColumnName].ToString(),null);
//}
object instance = Activator.CreateInstance(objType, true);
for (int i=0; i < properties.Length; i++)
{
FieldAttribute[] fieldAttributes = (FieldAttribute[])properties[i].GetCustomAttributes(fieldAttributeType, true);
if (fieldAttributes.Length > 0)
{
properties[i].SetValue(instance, dr[fieldAttributes[0].ColumnName].ToString(), null);
}
}
contacts.Add(instance );
}
contactData.DataSource= contacts;
contactData.DataBind();
}
}
public class Contact
{
string contact_ID;
[FieldAttribute("Contact_ID")]
public string Contact_ID
{
get {return contact_ID;}
set {contact_ID = value;}
}
}
打印 | 张贴于 2004-04-21 20:48:00 | Tag:Dot Net

留言反馈
多谢
用缓存速度提高了30-40%,原理很简单,当时咋就没想到测试这种方案呢:)
我的方案是可以指定映射,也可以指定Table,这样就到数据库里面取Schema, 用FieldName和ColumnName相等来映射; 比较适合l懒人,呵呵;
也有用customer attribute的
但估计没人像我这样BT的
我是直接用SQL从数据库中取结构信息的
当然结构信息都做了缓存处理
考虑到重用性, 我觉得这样的性能开销是可以接受的
数据结构:
public class DTOUser : ICloneable
{
public DTOUser() {}
public DTOUser(int Id, string Name, int Type, string Desc, DateTime CreateTime, byte[] Version)
{
this.Id = Id;
this.Name = Name;
this.Type = Type;
this.Desc = Desc;
this.CreateTime = CreateTime;
this.Version = Version;
}
public int Id;
public string Name;
public int Type;
public string Desc;
public System.DateTime CreateTime;
public byte[] Version=null;
public object Clone()
{
return this.MemberwiseClone();
}
}
2、我测试的表结构是这样的
CREATE TABLE [dbo].[TDalop] (
[autoid] [int] IDENTITY (1, 1) NOT NULL ,
[uid] [varchar] (12) NOT NULL ,
[code] [varchar] (50) NOT NULL ,
[name] [varchar] (50) NOT NULL ,
[salary] [numeric](18, 0) NOT NULL ,
[indate] [datetime] NULL ,
[remark] [varchar] (50) NULL ,
[ismanager] [bit] NOT NULL ,
[rowversion] [timestamp] NOT NULL,
[guid] [uniqueidentifier] NULL,
[photo] [image] NULL
) ON [PRIMARY]
GO
do while not list.eof
set contact = list.current(contact)
debug.print contact.name
list.movenext
loop
一种是EntityList(对RecordSet的包装),然后遍历(通过callbyname赋值),1000条数据,0.6s
一种是EntityCollection,将EntityList中的数据填充到Collection中(new 再 callbyname),同样数据,大概是2s多
所以我认为EntityList是对EntityCollection的一种很好的补充。
EntityList使用方法
dim contact as new contact
dim list as entitylist
....
do while not list.eof
set contact = list.current(contact)
debug.print contact.name
loop