Found a way which works. May be it's not that nice... I appreciate comments.
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq.Expressions;
using CHG.iCLASSFW.Base.Objects;
using CHG.iCLASSFW.Base.Shared;
using Remotion.Linq;
using Remotion.Linq.SqlBackend.MappingResolution;
using Remotion.Linq.SqlBackend.SqlStatementModel;
using Remotion.Linq.SqlBackend.SqlStatementModel.Resolved;
/// <summary>
/// <see cref="ResolvedHierarchicalTableInfo" /> represents the data source defined by multiple tables in a relational database.
/// </summary>
public class ResolvedHierarchicalTableInfo : ResolvedSimpleTableInfo, IResolvedTableInfo
{
#region "Members"
private ResolvedSimpleTableInfo m_MainTableInfo;
private ResolvedSimpleTableInfo m_JoinedTableInfo;
private SqlTable m_MainTable;
private SqlJoinedTable m_JoinedTable;
#endregion
private ResolvedJoinInfo m_JoinInfo;
#region "Constructors / Destructors"
/// <summary>
/// Initializes a new instance
/// </summary>
/// <param name="itemType">The BO item type</param>
/// <param name="tableAlias">The table alias</param>
/// <param name="objectInfo">The bo definition</param>
public ResolvedHierarchicalTableInfo(Type itemType, string tableAlias, string parentAlias, BusinessObjectDefinition objectInfo, BusinessObjectDefinition parentObjectInfo) : base(itemType, objectInfo.TableName, tableAlias)
{
ArgumentUtility.CheckNotNull("objectInfo", objectInfo);
ArgumentUtility.CheckNotNull("parentObjectInfo", parentObjectInfo);
ArgumentUtility.CheckNotNull("parentAlias", parentAlias);
// retrieve the relation items to the base object
dynamic relationItemsResult = Buffers.Instance.MetaInfo.GetRelation("select statement for joining hierachical objects", parentObjectInfo, objectInfo, null, null);
if ((!relationItemsResult.IsValid))
{
throw relationItemsResult.ToServiceException(null);
}
Expression expression = null;
foreach (void item_loopVariable in relationItemsResult.Response.Items)
{
item = item_loopVariable;
dynamic primaryColumn = new SqlColumnDefinitionExpression(item.PrimaryKeyField.PropertyInfo.PropertyType, parentAlias, item.PKTableFieldName, item.PrimaryKeyField.IsPartOfPrimaryKey);
dynamic foreignColumn = new SqlColumnDefinitionExpression(item.ForeignKeyField.PropertyInfo.PropertyType, tableAlias, item.FKTableFieldName, item.ForeignKeyField.IsPartOfPrimaryKey);
dynamic itemExpression = expression.Equal(primaryColumn, foreignColumn);
if ((expression == null))
{
expression = itemExpression;
} else
{
expression = expression.AndAlso(expression, itemExpression);
}
}
m_MainTableInfo = new ResolvedSimpleTableInfo(itemType, objectInfo.TableName, tableAlias);
m_JoinedTableInfo = new ResolvedSimpleTableInfo(parentObjectInfo.GetBusinessObjectType(), parentObjectInfo.TableName, parentAlias);
m_MainTable = new SqlTable(m_MainTableInfo, JoinSemantics.Inner);
m_JoinInfo = new ResolvedJoinInfo(m_JoinedTableInfo, expression);
m_JoinedTable = m_MainTable.GetOrAddLeftJoin(m_JoinInfo, relationItemsResult.Response.Items.First().ForeignKeyField.PropertyInfo);
}
#endregion
#region "Public methods"
public Expression ResolveReference(SqlTableBase sqlTable, IMappingResolver mappingResolver, IMappingResolutionContext context, UniqueIdentifierGenerator generator)
{
ArgumentUtility.CheckNotNull("sqlTable", sqlTable);
ArgumentUtility.CheckNotNull("mappingResolver", mappingResolver);
ArgumentUtility.CheckNotNull("context", context);
ArgumentUtility.CheckNotNull("generator", generator);
SqlEntityExpression sqlEntityExpression = mappingResolver.ResolveSimpleTableInfo(m_MainTableInfo, generator);
context.AddSqlEntityMapping(sqlEntityExpression, m_MainTable);
dynamic joinSqlEntityExpression = mappingResolver.ResolveSimpleTableInfo(m_JoinedTableInfo, generator);
context.AddSqlEntityMapping(joinSqlEntityExpression, m_JoinedTable);
return sqlEntityExpression;
}
public override ITableInfo Accept(ITableInfoVisitor visitor)
{
ArgumentUtility.CheckNotNull("visitor", visitor);
dynamic result = visitor.VisitSimpleTableInfo(this);
// required to get "GetResolvedTableInfo" called
SqlBackend.SqlGeneration.SqlTableAndJoinTextGenerator textbuilder = visitor as SqlBackend.SqlGeneration.SqlTableAndJoinTextGenerator;
if ((textbuilder != null))
{
textbuilder.CommandBuilder.Append(" {0} JOIN ".Frmt(m_MainTable.JoinSemantics));
}
IJoinInfoVisitor joinVisitor = visitor as IJoinInfoVisitor;
if ((joinVisitor != null))
{
joinVisitor.VisitResolvedJoinInfo(m_JoinInfo);
} else
{
visitor.VisitSqlJoinedTable(m_JoinedTable);
}
return result;
}
public override IResolvedTableInfo GetResolvedTableInfo()
{
return this;
// now "ResolveReference" get called
}
public override string ToString()
{
return m_MainTable.ToString();
}
#endregion
#region "Properties"
/// <summary>
/// Gets the used table alias
/// </summary>
/// <returns></returns>
public string TableAlias {
get { return base.TableAlias; }
}
/// <summary>
/// Gets the underlying item type
/// </summary>
/// <returns></returns>
public override Type ItemType {
get { return base.ItemType; }
}
#endregion
}