[C#] Microsoft.CodeAnalysis.CSharp.Scripting(Roslyn) 動態執行 C# Code,加入了LINQ 查詢
2017-02-02
上一篇文章我們提到了 Microsoft.CodeAnalysis.CSharp.Scripting(Roslyn) 動態執行 C# Code 簡單入門 ,但是遇到一個問題,如果我在程式碼裡面加入了關於LINQ的查詢就會出現:
未處理的例外狀況: Microsoft.CodeAnalysis.Scripting.CompilationErrorException: (4,38): error CS0234: The type or namespace name 'Linq' does not exist in the namespace 'System' (are you missing an assembly reference?) 於 Microsoft.CodeAnalysis.Scripting.ScriptBuilder.ThrowIfAnyCompilationErrors(DiagnosticBag diagnostics, DiagnosticFormatter formatter) 於 Microsoft.CodeAnalysis.Scripting.ScriptBuilder.CreateExecutor[T](ScriptCompiler compiler, Compilation compilation, CancellationToken cancellationToken) 於 Microsoft.CodeAnalysis.Scripting.Script`1.GetExecutor(CancellationToken cancellationToken) 於 Microsoft.CodeAnalysis.Scripting.Script`1.RunAsync(Object globals, Func`2 catchException, CancellationToken cancellationToken) 於 Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript.RunAsync[T](String code, ScriptOptions options, Object globals, Type globalsType, CancellationToken cancellationToken) 於 Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript.RunAsync(String code, ScriptOptions options, Object globals, Type globalsType, CancellationToken cancellationToken) 於 ScriptEngineUtility.Agent.Excute(String code) 於 C:\Users\no2don\Documents\Visual Studio 2015\Projects\DynamucRunCS\ScriptEngineUtility\Agent.cs: 行 25 於 ScriptEngineUtility.TestEngineLinq.Main() 於 C:\Users\no2don\Documents\Visual Studio 2015\Projects\DynamucRunCS\ScriptEngineUtility\TestEngineLinq.cs: 行 58
後來發現,其實在執行的時候可以加入引入什麼library
上篇文章原本的 code :
private static ScriptState<object> scriptState = null; public static dynamic Excute(string code) { scriptState = scriptState == null ? CSharpScript.RunAsync(code).Result : scriptState.ContinueWithAsync(code).Result; if (scriptState.ReturnValue != null && !string.IsNullOrEmpty(scriptState.ReturnValue.ToString())) return scriptState.ReturnValue; return null; }
之後加入 ScriptOptions 的 code :
private static ScriptState<object> scriptState = null; public static dynamic Excute(string code) { var scriptOptions = ScriptOptions.Default.WithReferences( typeof(System.Linq.EnumerableQuery<>).GetTypeInfo().Assembly ); scriptState = scriptState == null ? CSharpScript.RunAsync(code, scriptOptions).Result : scriptState.ContinueWithAsync(code, scriptOptions).Result; if (scriptState.ReturnValue != null && !string.IsNullOrEmpty(scriptState.ReturnValue.ToString())) return scriptState.ReturnValue; return null; }
執行程式 :
public static void Main() { var datas = new List<User>(); for (int i = 1; i <= 100; i++) { datas.Add(new User { Name = "Donma" + i, Age = i, Birth = new DateTime(1983, 5, 24).AddDays(i), Id = "NO" + i }); } var text = @" using System; using System.Collections.Generic; using System.Linq; public class User { public string Id { get; set; } public int Age { get; set; } public DateTime Birth { get; set; } public string Name { get; set; } } var datas = new List<User>(); for (int i = 1; i <= 100; i++) { datas.Add(new User {Name = ""Donma""+i,Age=i,Birth=new DateTime(1983,5,24).AddDays(i),Id=""NO"" + i}); } datas = datas.Where(x => x.Age <= 20).ToList(); return datas; "; dynamic test2 = Agent.Excute( text); if (test2 != null) { foreach (var c in test2) { Console.Write(c.Name + ","); } } }
這樣就可以執行LINQ的語法了,筆記一下,今天卡了我一下子。