Injecting a variable into the Mono.CSharp.Evaluator (runtime compiling a LINQ query from string)

后端 未结 2 868
情深已故
情深已故 2021-01-18 16:22

I\'m using the Mono.CSharp library to emit code. Following another question on SO (http://stackoverflow.com/questions/3407318/mono-compiler-as-a-service-mcs) I managed to g

相关标签:
2条回答
  • 2021-01-18 16:46

    I think you have a few options:

    1. Use static or ThreadStatic variables to exchange data between the caller and you string based code:

      namespace MyNs
      {
        public class MyClass
        {
       [ThreadStatic] // thread static so the data is specific to the calling thread
       public static string MyEnumerableVariable;
      
      
       public void DoSomething() 
       {
            Evaluator.ReferenceAssembly(Assembly.GetExecutingAssembly());
            Evaluator.Run("using MyNs;")
            // run the dynamic code
            var s = @"return (from contact in MyNs.MyClass.MyEnumerableVariable where contact.Name == ""John"" select contact).ToList();";
            Evaluator.Evaluate(s);
       }
      

      } }

    2. Return a delegate from your string code:

      
       public void DoSomething() 
       {

      // run the dynamic code var s = @"return new Func<string, IQueryable<MyNs.Model.Contact>, IList>((s,q) => (from contact in q where contact.Name == s select contact).ToList());"; var func = (Func<string, IQueryable<MyNs.Model.Contact>, IList>)Evaluator.Evaluate(s); var result = func("John", myQueryableOfContactsFromNHibernate);

      }

    3. Go the full blown route.
    
    string query = string.Format(
    @"using (var dc = new DataContext()) 
    {
      return (from contact in dc.Contacts where contact.Name == ""{0}"" select contact).ToList();
    }", "John");
    
    var result = Mono.CSharp.Evaluator.Evaluate(query);
    

    0 讨论(0)
  • 2021-01-18 17:01

    I didn't try this, but I guess you could use Mono compiler to create a delegate vthat takes IQueryable<Contract> as argument and returns the filtered query. Something like:

    IQueryable<Contact> contacts = GetContacts(); 
    string query = "new Func<IQueryable<Contact>, IQueryable<Contact>>(contracts =>
                      from contact in contacts 
                      where contact.Name == \"name\" 
                      select contact)"; 
    var res = Mono.CSharp.Evaluator.Evaluate(query); 
    

    Then you just need to cast res to an appropriate Func<,> type and invoke it to get the result.

    0 讨论(0)
提交回复
热议问题