Генерация Кода CodeDomProvider Завершается Неудачей С Определенным Синтаксисом Linq



Я использую CodeDomProvider для компиляции некоторого кода Linq и динамического выполнения запросов. Однако я столкнулся с очень странной проблемой.



Если мой запрос 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:




Не удалось загрузить файл или сборку '0 байт, загруженных из системы,
Версия=4.0.0.0, культуры=нейтральных, PublicKeyToken=b77a5c561934e089 "или"
одна из его зависимостей. Была предпринята попытка загрузить программу с помощью
неверный формат


541   3  

3 ответов:

Это, кажется, работает для меня:

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

Вы, вероятно, получаете BadImageFormatException, потому что ваш код на самом деле не компилируется в допустимую сборку. Это может быть связано с тем, что по умолчанию используется старый компилятор 2.0. Проверьте ссылку ниже для включения C# версии 3.5 (я не знаю, поддерживается ли 4.0, но вам это не нужно):

Http://blogs.msdn.com/b/lukeh/archive/2007/07/11/c-3-0-and-codedom.aspx

Также проверьте коллекцию Errors на CompilerResult, которая возвращается из метода CompileAssemblyFromSource(). Отказ от компиляции не делает чтобы создать исключение, необходимо вручную проверить наличие ошибок компиляции.

Я не нашел ответа, Как получить хорошую информацию об исключениях, однако я решил эту проблему. Библиотека классов, содержащая приведенный выше код компилятора, была установлена в значение AnyCpu, но контекст, в котором она выполнялась ASP.Net был х86. Так что это было причиной его сбоя, когда он пытался загрузить систему.dll, так как он загружал неправильную версию (или что-то глупое вроде этого).

Я буду счастлив дать кому-то другой ответ галочкой, если вы можете (а) выяснить, как получить реальную ошибку сообщение от этого или (b) загрузить правильный тип ссылки.

Comments

    Ничего не найдено.