数据持久化关联对象加载实现
前几天构想过持久化组件关联对象加载的方式,经过一段时间的思考决定把构想方案实现出来;用于替换自己原有持久化组件的关联加载方式。为了使加载方式更灵活,于是采用接口方式来描述加载过程。采用接口的好处就是开发人员完全可以根据自己的需来制定加载的方式;如:实时加载、延时加载或两者结合。这次的实现主要是关联加载和关联删除,实现的原则就是尽量以插件的方式直入到原有持久化组件中,这样可以更好地保证原有功能正确性。原有组件在数据查询和删除时对关联处理上下文对象进行检测,根据开发人员的设置进行功能的切入执行。
组件类结构图:
关联上下文对象
为了方便操作采用泛型的方式代替params Type[]的类型传递方式,根据情况需要重载了多版本的设置方法;由于结构的限制在设计时只允许最多9个关系类型设置。
{
Load(loader, typeof(T));
}
public static void Load<T, T1>(IRelationLoad loader)
{
Load(loader, typeof(T), typeof(T1));
}
public static void Load<T, T1, T2>(IRelationLoad loader)
{
Load(loader, typeof(T), typeof(T1), typeof(T2));
}
public static void Load<T, T1, T2, T3>(IRelationLoad loader)
{
Load(loader, typeof(T), typeof(T1), typeof(T2), typeof(T3));
}
public static void Load<T, T1, T2, T3, T4>(IRelationLoad loader)
{
Load(loader, typeof(T), typeof(T1), typeof(T2), typeof(T3), typeof(T4));
}
public static void Load<T, T1, T2, T3, T4, T5>(IRelationLoad loader)
{
Load(loader, typeof(T), typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5));
}
public static void Load<T, T1, T2, T3, T4, T5, T6>(IRelationLoad loader)
{
Load(loader, typeof(T), typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6));
}
public static void Load<T, T1, T2, T3, T4, T5, T6, T7>(IRelationLoad loader)
{
Load(loader, typeof(T), typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7));
}
public static void Load<T, T1, T2, T3, T4, T5, T6, T7, T8>(IRelationLoad loader)
{
Load(loader, typeof(T), typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8));
}
public static void Load<T, T1, T2, T3, T4, T5, T6, T7, T8, T9>(IRelationLoad loader)
{
Load(loader, typeof(T), typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8), typeof(T9));
}
static void Load(IRelationLoad loader,params Type[] types)
{
RelationContext ct = Context;
ct.LoadUp = true;
ct.LoadTypes.Clear();
if (HFSoft.StaticFunction.IsEmpty(types))
return;
foreach (Type item in types)
{
ct.LoadTypes.Add(item);
}
if (loader == null)
ct.RelationLoad = new RelationLoad();
else
ct.RelationLoad = loader;
}
关联加载接口
{
void Load(HFSoft.Data.IDataSession session, System.Collections.IList list, RelationAttribute relation, HFSoft.Data.Expressions.Expression exp);
}
{
IRelationLoad 成员
}
{
IRelationLoad 成员
}
HFSoft.Data.IDataSession session
用于描述当前处理的数据环境,通过此对象进行其他数据查询操作;当实现延时加载时可以取得相关的ConnectionString和Driver在数据加载时使用。
System.Collections.IList list
当前数据查询获取的列表
RelationAttribute relation
需要处理的关联描述
HFSoft.Data.Expressions.Expression exp
当前数据查询的条件,根据这个条件和relation映射出关联条件
关联删除接口
{
void Delete(HFSoft.Data.IDataSession session, RelationAttribute relation, HFSoft.Data.Expressions.Expression exp);
}
{
IRelationDelete 成员
}
HFSoft.Data.IDataSession session
用于描述当前处理的数据环境,通过些对象进行其他数据删除操作
RelationAttribute relation
需要处理的关联描述
HFSoft.Data.Expressions.Expression exp
当前数据删除的条件,根据这个条件和relation映射出关联条件
关联描述对象
RelationAttribute主要用于标记对象关联的信息,些信息用于对象关联查询和对象关联删除操作的依赖。
{
public RelationAttribute(RelationType rtype, string field)
{
RelationType = rtype;
LeftField = field;
RightField = field;
}
public RelationAttribute(RelationType rtype, string leftfield,string rightfield)
{
RelationType = rtype;
LeftField = leftfield;
RightField = rightfield;
}
public RelationAttribute(RelationType rtype,Type linktype,string leftfield, string rightfield)
{
RelationType = rtype;
LeftField = leftfield;
RightField = rightfield;
LinkType = linktype;
}
public RelationType mRelationType = RelationType.ToOne;
/// <summary>
/// 关联描述类型
/// [ToOne]一对一子关联
/// [ToParent]一对一父关联
/// [ToMany]一对多关联
/// [ManyToMany]多对多关联
/// </summary>
public RelationType RelationType
{
get
{
return mRelationType;
}
set
{
mRelationType = value;
}
}
private Type mLinkType;
/// <summary>
/// 关联连接对象
/// 用于ManyToMany多对多关联
/// </summary>
public Type LinkType
{
get
{
return mLinkType;
}
set
{
mLinkType = value;
}
}
private Type mLeftType;
/// <summary>
/// 左关联类型
/// 当前实体类型
/// </summary>
public Type LeftType
{
get { return mLeftType; }
set { mLeftType = value; }
}
private Type mRightType;
/// <summary>
/// 右关联类型
/// 关联引用属性类型
/// </summary>
public Type RightType
{
get
{
return mRightType;
}
set
{
mRightType = value;
}
}
private PropertyInfo mRelationProperty;
/// <summary>
/// 关联属性
/// </summary>
public PropertyInfo RelationProperty
{
get { return mRelationProperty; }
set { mRelationProperty = value; }
}
public HFSoft.Data.IQuery CreateQuery(HFSoft.Data.IDataSession session)
{
IQuery query = session.CreateQuery(QueryTable);
query.Selects = new FieldAdapter[] {new FieldAdapter("*",RightTable)};
return query;
}
private string mLeftField;
public string LeftField
{
get
{
return mLeftField;
}
set
{
mLeftField = value;
}
}
private string mRightField;
public string RightField
{
get
{
return mRightField;
}
set
{
mRightField = value;
}
}
internal Table RightTable
{
get
{
return null;
}
}
internal Table LeftTable
{
get
{
return null;
}
}
internal Table LinkTable
{
get
{
return null;
}
}
private RelationTable mQueryTable;
internal Table QueryTable
{
get
{
if (mQueryTable == null)
{
CreateQueryTable();
}
return mQueryTable;
}
}
private void CreateQueryTable()
{
if (RelationType == RelationType.ManyToMany)
{
string[] lfields = LeftField.Split(new char[] { '-'});
if (lfields.Length > 1)
{
mQueryTable = LeftTable.INNER(LinkTable, new FieldAdapter(lfields[0], LeftTable),
new FieldAdapter(lfields[1], LinkTable));
}
else
{
mQueryTable = LeftTable.INNER(LinkTable, new FieldAdapter(lfields[0], LeftTable),
new FieldAdapter(lfields[0], LinkTable));
}
string[] rfields = RightField.Split(new char[] { '-' });
if (rfields.Length > 1)
{
mQueryTable &= LinkTable.INNER(RightTable, new FieldAdapter(rfields[0], LinkTable),
new FieldAdapter(rfields[1], RightTable));
}
else
{
mQueryTable &= LinkTable.INNER(RightTable, new FieldAdapter(rfields[0], LinkTable),
new FieldAdapter(rfields[0], RightTable));
}
}
else
{
mQueryTable = LeftTable.INNER(RightTable, new FieldAdapter(LeftField, LeftTable),
new FieldAdapter(RightField, RightTable));
}
}
}