将变量注入 Mono.CSharp.Evaluator(运行时从字符串编译 LINQ 查询)

Kev*_*vin 5 c# linq expression-trees

我正在使用 Mono.CSharp 库来发出代码。在关于 SO (http://stackoverflow.com/questions/3407318/mono-compiler-as-a-service-mcs) 的另一个问题之后,我设法让 Mono.CSharp 在 Microsoft CLR 上正确评估。

为了在我的应用程序中增加灵活性,我希望能够在运行时自定义查询 - 通过允许用户提供 LINQ 查询作为字符串,该字符串在执行时被解析并命中数据库。

鉴于此基本代码片段:

IQueryable<Contact> contacts = GetContacts();
string query = "from contact in contacts
                where contact.Name == \"name\"
                select contact";
var queryableResult = Mono.CSharp.Evaluator.Evaluate(query);
Run Code Online (Sandbox Code Playgroud)

如何将联系人变量“注入”到 Mono.CSharp.Evaluator 中以作为查询的一部分进行评估?我会以正确的方式解决这个问题吗?最后,我需要结果表达式或来自“查询”字符串的 IQueryable。

Jef*_*eff 5

我想你有几个选择:

  1. 使用静态或 ThreadStatic 变量在调用者和基于字符串的代码之间交换数据:

    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);
     }
    
    Run Code Online (Sandbox Code Playgroud)

    } }

  2. 从您的字符串代码返回一个委托:

    
     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);

    }

    Run Code Online (Sandbox Code Playgroud)

  3. 走完整的路线。

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);
Run Code Online (Sandbox Code Playgroud)