public string GetFromPart()
{
if (MainFrom == null)
throw new InvalidOperationException("A query must have a from part");
var sb = new StringBuilder();
if (AdditionalJoins.Any(it => EndsWithQuerySource(it.FromExpression as MemberExpression)))
sb.AppendFormat("FROM ({0}) sq ", GetInnerFromPart());
else
sb.AppendFormat("FROM {0}", GetQuerySourceFromExpression(MainFrom.ItemName, MainFrom.ItemType, MainFrom.FromExpression));
var emptyJoins =
(from j in AdditionalJoins
let sqe = j.FromExpression as SubQueryExpression
where sqe != null
&& sqe.QueryModel.ResultOperators.Count == 1
&& sqe.QueryModel.ResultOperators[0] is DefaultIfEmptyResultOperator
select new { j, sqe })
.ToList();
var groupPairs =
(from aj in emptyJoins
let mfe = aj.sqe.QueryModel.MainFromClause.FromExpression as QuerySourceReferenceExpression
where mfe != null
select new { aj.j, g = mfe.ReferencedQuerySource })
.ToList();
foreach (var aj in AdditionalJoins)
{
var me = aj.FromExpression as MemberExpression;
if (EndsWithQuerySource(me))
continue;
if (groupPairs.Any(it => it.j == aj))
continue;
var ej = emptyJoins.Find(it => it.j == aj);
if (ej != null)
{
var qm = ej.sqe.QueryModel;
var sel = qm.SelectClause.Selector as QuerySourceReferenceExpression;
if (sel != null && sel.ReferencedQuerySource.Equals(qm.MainFromClause) && qm.BodyClauses.Count > 0)
{
var wc = qm.BodyClauses.Where(it => it is WhereClause).Cast<WhereClause>().ToList();
if (wc.Count == qm.BodyClauses.Count)
{
var mfc = qm.MainFromClause;
mfc.ItemName = aj.ItemName;
sb.AppendFormat("{0} LEFT JOIN {1} ON {2}",
Environment.NewLine,
GetQuerySourceFromExpression(mfc.ItemName, mfc.ItemType, mfc.FromExpression),
string.Join(" AND ", wc.Select(it => GetSqlExpression(it.Predicate))));
continue;
}
}
}
sb.AppendFormat("{0} CROSS JOIN {1}",
Environment.NewLine,
GetQuerySourceFromExpression(aj.ItemName, aj.ItemType, aj.FromExpression));
}
foreach (var j in Joins)
{
sb.AppendFormat("{0} INNER JOIN {1} ON ({2}) = ({3}){0}",
Environment.NewLine,
GetQuerySourceFromExpression(j.ItemName, j.ItemType, j.InnerSequence),
GetSqlExpression(j.InnerKeySelector),
GetSqlExpression(j.OuterKeySelector));
}
foreach (var gj in GroupJoins)
{
var aj = groupPairs.FirstOrDefault(it => it.g == gj);
if (aj == null)
throw new FrameworkException("Can't find group join part!");
gj.ItemName = aj.j.ItemName;
gj.JoinClause.ItemName = aj.j.ItemName;
sb.AppendFormat("{0} LEFT JOIN {1} ON ({2}) = ({3}){0}",
Environment.NewLine,
GetQuerySourceFromExpression(gj.ItemName, gj.ItemType, gj.JoinClause.InnerSequence),
GetSqlExpression(gj.JoinClause.InnerKeySelector),
GetSqlExpression(gj.JoinClause.OuterKeySelector));
}
sb.AppendLine();
return sb.ToString();
}