[C#] Microsoft.CodeAnalysis.CSharp.Scripting(Roslyn) 動態執行 C# Code,加入了LINQ 查詢

2017-02-02

 

上一篇文章我們提到了 Microsoft.CodeAnalysis.CSharp.Scripting(Roslyn) 動態執行 C# Code 簡單入門 ,但是遇到一個問題,如果我在程式碼裡面加入了關於LINQ的查詢就會出現:
image

錯誤訊息:
未處理的例外狀況: 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 + ",");
                }
            }

        }

image

這樣就可以執行LINQ的語法了,筆記一下,今天卡了我一下子。


當麻許的超技八 2014 | Donma Hsu Design.