关联加载IRelationLoad的实现代码(即时和延时)
/**//// <summary>
/// 关联加载适配对象
/// </summary>
public class RelationLoadAdapter:IRelationLoad
{
IRelationLoad 成员#region IRelationLoad 成员
//加载关联数据
void IRelationLoad.Load(HFSoft.Data.IDataSession session, System.Collections.IList list, RelationAttribute relation, HFSoft.Data.Expressions.Expression exp)
{
if (HFSoft.StaticFunction.IsEmpty(list))
return;
if (relation.RelationType == RelationType.ManyToMany ||
relation.RelationType == RelationType.ToMany)//一对多或多对多
{
LoadToMany(session, list, relation, exp);
}
else//一对一
{
LoadToOne(session, list, relation, exp);
}
}
#endregion
//一对一加载过程
protected virtual void LoadToOne(HFSoft.Data.IDataSession session, System.Collections.IList list, RelationAttribute relation, HFSoft.Data.Expressions.Expression exp)
{
HFSoft.Data.ITableView tv = HFSoft.Invoker.GetCreate(relation.RightType) as HFSoft.Data.ITableView;
HFSoft.Data.IQuery query = null;
Hashtable hash = new Hashtable();
object key;//引用关联值
System.Collections.IDictionary rightrecord;
query = relation.GetRightQuery(session,exp);
rightrecord = query.ListMap(relation.RightType, relation.RightMapProperty);
if (list.Count == 1)//当前查询数据只有一条记录
{
if (rightrecord.Count > 0)//当存在关联记录时
{
IEnumerator en = rightrecord.Keys.GetEnumerator();
en.Reset();
HFSoft.Invoker.SetValue(list[0], relation.RelationProperty, rightrecord[en.Current]);
}
return;
}
foreach (object item in list)//编辑左对象列表
{
key = HFSoft.Invoker.GetValue(item, relation.LeftProperty);
HFSoft.Invoker.SetValue(item, relation.RelationProperty, rightrecord[key]);
}
hash.Clear();
}
//多对多加载过程
protected virtual void LoadToMany(HFSoft.Data.IDataSession session, System.Collections.IList list, RelationAttribute relation, HFSoft.Data.Expressions.Expression exp)
{
Expression newexp = null;
string[] lfields = relation.LeftField.Split(new char[] { '-'});
System.Collections.IList childlist;
foreach (object item in list)
{
newexp = new ObjectField(lfields[0], relation.LeftTable) == HFSoft.Invoker.GetValue(item, relation.LeftProperty);
IQuery query = relation.GetRightQuery(session,newexp);
childlist = query.List(relation.RightType);
HFSoft.Invoker.SetValue(item,relation.LeftProperty,childlist);
}
}
}
/**//// <summary>
/// 集合即时加载
/// </summary>
public class RelationLoad:RelationLoadAdapter
{
//多对多加载过程
protected override void LoadToMany(HFSoft.Data.IDataSession session, System.Collections.IList list, RelationAttribute relation, HFSoft.Data.Expressions.Expression exp)
{
HFSoft.Data.ITableView tv = HFSoft.Invoker.GetCreate(relation.RightType) as HFSoft.Data.ITableView;
IList linkrecord = null;
IList rightrecord = null;
HFSoft.Data.IQuery query = null;
if (relation.RelationType == RelationType.ManyToMany)
{
//加载LinkType数据
query = relation.GetLinkQuery(session,exp);
linkrecord = query.List(relation.LinkType);
}
query = relation.GetRightQuery(session,exp);
rightrecord = query.List(relation.RightType);
if (list.Count == 1)//当处理一条记录时
{
HFSoft.Invoker.SetValue(list[0], relation.RelationProperty, rightrecord);
return;
}
if (relation.RelationType == RelationType.ManyToMany)//多对多加载
{
doManyToMany(list, rightrecord,linkrecord,relation);
}
else//一对多加载
{
doToMany(list, rightrecord,relation);
}
}
//一对多加载过程
void doToMany(System.Collections.IList leftrecord, System.Collections.IList rightrecord,RelationAttribute relation)
{
Hashtable hash = new Hashtable();
System.Collections.IList childlist;
object array;
foreach (object item in leftrecord)
{
array = Activator.CreateInstance(typeof(List<>).MakeGenericType(relation.RightType));
HFSoft.Invoker.SetValue(item, relation.RelationProperty, array);
hash.Add(HFSoft.Invoker.GetValue(item, relation.LeftProperty), item);
}
foreach (object item in rightrecord)
{
childlist = (IList)HFSoft.Invoker.GetValue(hash[HFSoft.Invoker.GetValue(item, relation.RightProperty)], relation.RelationProperty);
childlist.Add(item);
}
hash.Clear();
}
//多对多加载过程
void doManyToMany(System.Collections.IList leftrecord, System.Collections.IList rightrecord, System.Collections.IList linkrecord, RelationAttribute relation)
{
int count = leftrecord.Count > linkrecord.Count ? leftrecord.Count : linkrecord.Count;
Hashtable linkhash = new Hashtable();
Hashtable lefthas = new Hashtable();
IList many;
object item;
object key;
//-----------------------------
//根据关连对象构造出右表键值对左表键值列表哈希表
//-----------------------------
for (int i = 0; i < count; i++)//整理左对象列表索引
{
if (i < linkrecord.Count)
{
item = linkrecord[i];
key = HFSoft.Invoker.GetValue(item, relation.LinkRightProperty);
if (linkhash.ContainsKey(key))
{
((ArrayList)linkhash[key]).Add(HFSoft.Invoker.GetValue(item, relation.LinkLeftProperty));
}
else
{
ArrayList lst = new ArrayList();
lst.Add(HFSoft.Invoker.GetValue(item, relation.LinkLeftProperty));
linkhash.Add(key, lst);
}
}
if (i < leftrecord.Count)//建立左对象哈希表
{
item = leftrecord[i];
many = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(relation.RightType));
lefthas.Add(HFSoft.Invoker.GetValue(item, relation.LeftProperty), item);
HFSoft.Invoker.SetValue(item, relation.RelationProperty, many);
}
}
foreach (object ritem in rightrecord)//遍历右对象列表,并把相关对象添加到左表中
{
key = HFSoft.Invoker.GetValue(ritem, relation.RightProperty);
if (linkhash.ContainsKey(key))
{
foreach (object i in (IList)linkhash[key])//获取左表记录相关键列表
{
item = lefthas[i];
if (item != null)//添加到左对象属性上
{
many = (IList)HFSoft.Invoker.GetValue(item, relation.RelationProperty);
many.Add(ritem);
}
}
}
}
linkhash.Clear();
lefthas.Clear();
}
}
/**//// 集合延时加载
/// </summary>
public class RelationLazyLoad:RelationLoadAdapter
{
//一对多加载过程
protected override void LoadToMany(HFSoft.Data.IDataSession session, System.Collections.IList list, RelationAttribute relation, HFSoft.Data.Expressions.Expression exp)
{
ISetLoadInfo lazyload = null;
Expression newexp = null;
string[] lfields = relation.LeftField.Split(new char[] { '-'});
foreach (object item in list)
{
lazyload = (ISetLoadInfo)Activator.CreateInstance(typeof(LazyLoadList<>).MakeGenericType(relation.RightType));
HFSoft.Invoker.SetValue(item, relation.RightProperty, lazyload);
newexp = new ObjectField(lfields[0], relation.LeftTable) == HFSoft.Invoker.GetValue(item, relation.LeftProperty);
lazyload.SetInfo(session.Driver, session.ConnectionString, newexp, relation);
}
}
}