Luis Valencia
Luis Valencia

Reputation: 34008

Dynamic Linq with date fields

I am building a dynamic query builder using the dynamic linq library. SO far its working fine with bool, number and text, but not with dates.

I wonder what should be the format for dates to work fine.

THis is the code that executes what sb.ToString returns.

private string BuildQuery()
        {
            var sb = new StringBuilder();
            //var list = RequestBaseBL.GetRequestByCustomQuery("RequestNumber == \"12\"");
        #region 1st ROW of the QUERY
        if (ColumnType(DdlColumn1.SelectedValue) == "Text")
        {
            if(DdlOperator1.SelectedValue == "==")
            {
                sb.Append(DdlColumn1.SelectedValue);
                sb.Append(DdlOperator1.SelectedValue);
                sb.Append("\"" + TxtValue1.Text + "\"");
            }
            if (DdlOperator1.SelectedValue == "<>")
            {
                sb.Append(DdlColumn1.SelectedValue);
                sb.Append(DdlOperator1.SelectedValue);
                sb.Append("\"" + TxtValue1.Text + "\"");
            }
            if (DdlOperator1.SelectedValue == "LIKE")
            {
                sb.Append(string.Format("{0}.Contains(\"{1}\")", DdlColumn1.SelectedValue, TxtValue1.Text));
            }
            if (DdlOperator1.SelectedValue == "NOT LIKE")
            {
                sb.Append(string.Format("!{0}.Contains(\"{1}\")", DdlColumn1.SelectedValue, TxtValue1.Text));
            }
        }

        if (ColumnType(DdlColumn1.SelectedValue) == "Number")
        {
            sb.Append(DdlColumn1.SelectedValue);
            sb.Append(DdlOperator1.SelectedValue);
            sb.Append(TxtValue1.Text);
        }

        if (ColumnType(DdlColumn1.SelectedValue) == "Date")
        {
            sb.Append(DdlColumn1.SelectedValue);
            sb.Append(DdlOperator1.SelectedValue);
            sb.Append(TxtValue1.Text);
        }

        if (ColumnType(DdlColumn1.SelectedValue) == "Bool")
        {
            sb.Append(DdlColumn1.SelectedValue);
            sb.Append(DdlOperator1.SelectedValue);
            sb.Append(TxtValue1.Text);
        }

        #endregion  


        return sb.ToString();
    }


  string strSql = BuildQuery();
            try
            {
                var list = RequestBaseBL.GetRequestByCustomQuery(strSql, DdlRequestType.SelectedValue).ToList();



private static void AddDateOperatorsToList(Dictionary<string, string> operators)
            {
                operators.Add("=", "Equals");
                operators.Add("<>", "Not Equals");
                operators.Add(">", "Greater than");
                operators.Add(">=", "Greater or equal than");
                operators.Add("<", "Less than");
                operators.Add("<=", "Less or equal than");
            }

Update 1:

The error is: Operator '=' incompatible with operand types 'DateTime' and 'Int32'

The sb.toString()

? sb.ToString() "RequestDate=12/12/2015"

Update 2:

Error of Update 2:

No applicable method 'Parse' exists in type 'DateTime'

if (ColumnType(DdlColumn1.SelectedValue) == "Date")
                {
                    sb.AppendFormat("DateTime.Parse({0})", DdlColumn1.SelectedValue);
                    var str = string.Format("{0} {1} {2}", DdlColumn1.SelectedValue, DdlOperator1.SelectedValue,
                                               DateTime.Parse(TxtValue1.Text));
                    //sb.Append(DdlColumn1.SelectedValue);
                    //sb.Append(DdlOperator1.SelectedValue);
                    //sb.Append(TxtValue1.Text);
                    sb.Append(str);
                }

Update 3:

Didnt work either

if (ColumnType(DdlColumn1.SelectedValue) == "Date")
                {
                    var date = DateTime.Parse(TxtValue1.Text);
                    sb.Append(DdlColumn1.SelectedValue);
                    sb.Append(DdlOperator1.SelectedValue);
                    sb.Append("\"" + date.ToUniversalTime() + "\"");
                    //sb.Append(date.ToUniversalTime());
                }

enter image description here

Upvotes: 2

Views: 3404

Answers (1)

Chris Gessler
Chris Gessler

Reputation: 23113

I'm currently using System.Dynamic.Linq and use a double equal with a DateTime object.

case "Equals":
    myDictionary.Add("MyField.Date ==", dt1);
    break;

Later I convert the keys in the dictionary to a string and values to an array (notice the @ symbol usage):

if (myDictionary.Keys.Count > 0)
{
  var conditions = myDictionary.Keys.Select((key, idx) => string.Format("{0} (@{1})", key, idx));

  // in .NET 4, the ToArray() part can go away
  predicateString = string.Join(" and ", conditions.ToArray());
  predicateValues = myDictionary.Values.ToArray();
}

Then call AsQueryable().Where()

return myList.AsQueryable().Where(predicateString, predicateValues).ToList();

I believe doing it this way eliminates the need to deal with the DateTime object as a string.

Upvotes: 1

Related Questions