Hi,
I found a lot of inspiration in this thread.
Here's my ISNULL implementation, based on a field and a value. It can (and prollie should) be extended for your purpose.
It's written in C# (.Net2), for SQL Server 2000 and using 1.0.2005.1 version of LLBLGen (the latest before 2 that is).
using System;
using System.Collections;
using System.Text;
using System.Data;
using SD.LLBLGen.Pro.ORMSupportClasses;
namespace Dipica.BM.LLBLGenCustom
{
[Serializable]
public class IsNullExpression : Expression
{
#region class member declarations
private string m_DefaultValue;
private Type m_type;
#endregion
public IsNullExpression(IEntityField field, string defaultValue, Type type)
: base(field, ExOp.None, defaultValue)
{
m_DefaultValue = defaultValue;
m_type = type;
}
public IsNullExpression()
: base()
{
m_DefaultValue = String.Empty;
m_type = null;
}
public override string ToQueryText(ref int uniqueMarker, bool inHavingClause)
{
StringBuilder str = new StringBuilder();
OperandToText(str, this.LeftOperand, ref uniqueMarker, true, inHavingClause);
str.Append(",");
OperandToText(str, this.RightOperand, ref uniqueMarker, false, inHavingClause);
return String.Format("ISNULL({0})", str.ToString());
}
private void OperandToText(StringBuilder str, IExpressionElement operand, ref int uniqueMarker, bool isLeft, bool inHavingClause)
{
IExpressionFieldElement element = new ExpressionFieldElement();
switch (operand.Type)
{
case ExpressionElementType.Field:
element = (ExpressionFieldElement)operand;
IEntityFieldCore core = (IEntityFieldCore)element.Contents;
str.AppendFormat("{0}", DatabaseSpecificCreator.CreateFieldName(core, element.PersistenceInfo, core.Name, core.ObjectAlias, ref uniqueMarker, inHavingClause));
if (core.ExpressionToApply != null)
{
this.Parameters.AddRange(core.ExpressionToApply.Parameters);
}
break;
case ExpressionElementType.Value:
if (m_type == typeof(DateTime))
str.AppendFormat("{0}", "CONVERT(DATETIME,'" + operand.Contents.ToString() + "')");
else
throw new NotImplementedException("Only datetime is implemented as IsNull param.");
break;
}
}
#region properties
public string DefaultValue
{
get { return m_DefaultValue; }
set { m_DefaultValue = value; }
}
#endregion
}
}
It's used as follows (pretty complex example...):
// filter to take the latest contract based upon the datedeparture
filter.AddWithAnd(new FieldCompareSetPredicate(
ContractFields.MonthDateDeparture.SetExpression(new LLBLGenCustom.IsNullExpression(ContractFields.MonthDateDeparture, "01-01-3000", typeof(DateTime))),
ContractFields.MonthDateDeparture.SetObjectAlias("c").SetExpression(new LLBLGenCustom.IsNullExpression(ContractFields.MonthDateDeparture.SetObjectAlias("c"), "01-01-3000", typeof(DateTime))),
SetOperator.Equal,
(ContractFields.EmploymentOid.SetObjectAlias("c") == EmploymentFields.Oid),
null,
String.Empty,
1,
new SortExpression(ContractFields.MonthDateDeparture.SetObjectAlias("c") | SortOperator.Descending)));
The filter above took me a lot of time to write out, but Walaa asked the right questions and gave the correct tips.
But you'll see the flexibility and usage (I hope).
I hope it'll have a bit of use.
Koen