ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c# – CodeDomProvider代码生成因某些Linq语法而失败

2019-06-30 07:54:38  阅读:348  来源: 互联网

标签:c compilation


我正在使用CodeDomProvider to compile some Linq code并动态执行查询.但是,我遇到了一个非常奇怪的问题.

如果我生成的代码中的Linq查询看起来像这样,一切正常:

namespace Dynamic
{
    using System.Linq;
    using System.Collections.Generic;

    public static class Query
    {
        public static int GetRecords()
        {
            MyData.Data.DataMart container = new MyData.Data.DataMart();
            return (container.EventDetails).Count();
        }
    }
}

这编译并运行得很好.但是,如果我将linq查询更改为以下内容,则无法编译:

return (from e in container.EventDetails select e).Count();

如果我把它作为静态代码,它工作正常,但如果我尝试使用CodeDomProvider编译它失败(我没有找到任何好的方法来获取错误消息为什么它失败).我想使用from-in-select样式的语法,因为这将使我更容易生成linq查询,但我无法弄清楚它们为什么不编译.

您可以在本文顶部的链接中看到我用来编译此代码段的一些代码.

谢谢!

编辑:从我链接到的帖子中复制代码:

CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
CompilerParameters cp = new CompilerParameters();
cp.GenerateInMemory = true;
cp.ReferencedAssemblies.Add("mscorlib.dll");
cp.ReferencedAssemblies.Add("System.dll");
cp.ReferencedAssemblies.Add("System.Core.dll");
cp.ReferencedAssemblies.Add("System.Data.Linq.dll");
cp.ReferencedAssemblies.Add("System.Data.Entity.dll");
cp.ReferencedAssemblies.Add("MyApp.Data.dll");

var results = provider.CompileAssemblyFromSource(cp, source);
var assm = results.CompiledAssembly; 

Edit2:就异常而言,我在第二行到最后一行代码上得到一个异常(var results = …). BadImageFormatException是一个例外:

Could not load file or assembly ‘0 bytes loaded from System,
Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089’ or
one of its dependencies. An attempt was made to load a program with an
incorrect format

解决方法:

这似乎对我有用:

    static void Main(string[] args)
    {
        string sourceCode = @"namespace Dynamic {
using System.Linq;
using System.Collections.Generic;

public static class Query
{
    public static int GetRecords()
    {
        MyApp.Data.DataMart container = new MyApp.Data.DataMart();
        //return (container.EventDetails).Count();
        return (from e in container.EventDetails select e).Count();
    }
} }";

        string sDynamDll = "Dynamic.dll";
        string sDynamClass = "Query";
        string sDynamMethod = "GetRecords";

        System.CodeDom.Compiler.CompilerParameters cp = new CompilerParameters();
        cp.GenerateExecutable = false;
        cp.GenerateInMemory = true;
        cp.OutputAssembly = sDynamDll;
        cp.ReferencedAssemblies.Add("mscorlib.dll");
        cp.ReferencedAssemblies.Add("System.dll");
        cp.ReferencedAssemblies.Add("System.Core.dll");
        cp.ReferencedAssemblies.Add("System.Data.Linq.dll");
        cp.ReferencedAssemblies.Add("System.Data.Entity.dll");
        cp.ReferencedAssemblies.Add("MyApp.Data.dll");

        var providerOptions = new Dictionary<string, string>();
        providerOptions.Add("CompilerVersion", "v4.0");
        CodeDomProvider compiler = CodeDomProvider.CreateProvider("C#", providerOptions);
        CompilerResults cr = compiler.CompileAssemblyFromSource(cp, sourceCode);
        if (cr.Errors.HasErrors)
        {
            StringBuilder errors = new StringBuilder("Compiler Errors :\r\n");
            foreach (CompilerError error in cr.Errors)
            {
                errors.AppendFormat("Line {0},{1}\t: {2}\n", error.Line, error.Column, error.ErrorText);
            }
        }

        // verify assembly
        Assembly theDllAssembly = null;
        if (cp.GenerateInMemory)
            theDllAssembly = cr.CompiledAssembly;
        else
            theDllAssembly = Assembly.LoadFrom(sDynamDll);

        Type theClassType = theDllAssembly.GetType(sDynamClass);

        foreach (Type type in theDllAssembly.GetTypes())
        {
            if (type.IsClass == true)
            {
                if (type.FullName.EndsWith("." + sDynamClass))
                {
                    theClassType = type;
                    break;
                }
            }
        }

        // invoke the method
        if (theClassType != null)
        {
            object[] method_args = new object[] { };

            Object rslt = theClassType.InvokeMember(
                sDynamMethod,
              BindingFlags.Default | BindingFlags.InvokeMethod,
                   null,
                   null, // for static class
                   method_args);

            Console.WriteLine("Results are: " + rslt.ToString());
        }

        Console.ReadKey();
    }

标签:c,compilation
来源: https://codeday.me/bug/20190630/1334731.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有