DateTime in roslyn CSharpScript returns 'expecting ;'

810 views Asked by At

Use of DateTime within the roslyn CSharpScript evaluator returns error code 'Expected ;' while strings work fine.

Using Visual Studio 2019 with Microsoft.CodeAnalysis.Common and Microsoft.CodeAnalysis.CSharp.Scripting 3.3.1

Understanding that the evaluator requires configuration, added DateTime assembly along with the custom class assembly.

public class Install
    {
        public int InstallId { get; set; }
        public int RegistrationId { get; set; }
        public int EnvironmentId { get; set; }
        public DateTime SubmitDateTime { get; set; }
        public string SubmitIdentity { get; set; }
        public DateTime TargetDateTime { get; set; }
        public string InstallerIdentity { get; set; }
        public DateTime? StartDateTime { get; set; }
        public DateTime? StopDateTime { get; set; }
        public string Status { get; set; }
    }
string queryText;
var fooFuture = DateTime.Now.AddDays(7);
var fooPast = DateTime.Now.AddDays(-7);

switch (TimeFrame)
  {
    case "future":  // fails (expected) //
       queryText = $"i => i.TargetDateTime < fooFuture";
       break;
    case "current":  // works //
       queryText = "i => i.Status == \"In Progress\"";
       break;
    case "past":   // fails with interpolation -- expecting ; //
       queryText = $"i => i.TargetDateTime > {fooPast}";
       break;
    default:      // fails with DateTime -- expecting ; //
       queryText = $"i => i.TargetDateTime < {DateTime.Now.AddDays(15)} && i.TargetDateTime > {DateTime.Now.AddDays(-15)}";
       break;
   }

ScriptOptions options = ScriptOptions.Default
  .AddReferences(typeof(Install).Assembly)
  .AddReferences(typeof(System.DateTime).Assembly);

Func<Install, bool> queryTextExpression = await CSharpScript.EvaluateAsync<Func<Install, bool>>(queryText, options);

Cannot understand here why a basic DateTime object causes issues.

String resolves to "i => i.TargetDateTime > 10/25/2019 11:00:00 AM". Wrapping in quotes causes it to be interpreted as string.

EDIT: I should add that hard-coding the string to the example above also fails with same error message, leading me to believe it is a parsing issue? It's not sure how to handle the characters within a DateTime object?

1

There are 1 answers

7
Matt Johnson-Pint On BEST ANSWER

The problem is as you said - the string is resolving to "i => i.TargetDateTime > 10/25/2019 11:00:00 AM" which is not valid C# code. Even if you added quotes, you can't directly compare a DateTime to a string

Ultimately, you either need to be comparing objects of the same type. Either string to string, DateTime to DateTime, long to long, etc. I prefer to keep them as DateTime objects.

Thus, you need to construct a DateTime on the right-hand side of the expression.

One way would be to use the DateTime constructor, like this:

queryText = $"i => i.TargetDateTime > new System.DateTime({fooPast.Ticks}, System.DateTimeKind.{fooPast.Kind})";

Another, arguably cleaner mechanism would be through the built-in binary serialization methods, which take both Ticks and Kind into account in a single value:

queryText = $"i => i.TargetDateTime > System.DateTime.FromBinary({fooPast.ToBinary()})";