2012-03-07 7 views
3

私はCodeDomProvider to compile some Linq codeを使用しており、動的にクエリを実行しています。しかし、私は非常に奇妙な問題にぶつかっています。特定のLinq構文でCodeDomProviderコードの生成に失敗する

このすべての作品のように生成されたコードの私の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でそれをコンパイルしようとするならば、それが失敗した(と私なぜ失敗するのかについてのエラーメッセージを得る良い方法が見つかっていない)。私はlinqクエリを生成するのが簡単になるので、from-in-selectスタイルの構文を使用したいと思いますが、なぜそれらがコンパイルされていないのかわかりません。

このスニペットをコンパイルするために使用するコードの一部は、この記事の一番上にあるリンクからご覧いただけます。

ありがとうございます!

編集:ポストからコードをコピー私はリンクへ:

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に2番目の例外を取得結果= ...)。

またはその依存関係の 1「 バージョン= 4.0.0.0、文化=中立、なPublicKeyToken = b77a5c561934e089、システムからロードされた0バイト」ファイルまたはアセンブリをロードできませんでした:例外がBadImageFormatExceptionです。試みはあなたのコードが実際に有効なアセンブリにコンパイルされていないので、あなたはおそらくBadImageFormatExceptionを取得している 間違ったフォーマット

+1

私たちがここで解決すべき問題?コンパイルしようとすると、エラー情報を得ることができないという事実はもっと重要です。コンパイルコードを含めることはできますか? –

+0

私は両方の問題を同時に解決するエラー情報を私に得ることができると思います。 :) MyApp.Data.dllには、自分のEntity Frameworkエンティティが含まれています。 – Bryant

+0

[CodeDomProviderコード生成はWebプロジェクトでは失敗しますが、コンソールアプリケーションでは失敗します](http://stackoverflow.com/questions/9577139/codedomprovider-code-generation-fails-in-web-project-but-not-console- app) –

答えて

0

良い例外情報を得る方法の答えが見つかりませんでしたが、私はこの問題を解決しました。上記のコンパイラコードを含むクラスライブラリはAnyCpuに設定されていましたが、ASP.Netで実行されていたコンテキストはx86でした。これは、間違ったバージョン(またはそのような愚かなもの)をロードしていたので、System.dllを読み込もうとしたときに失敗していました。

(a)実際のエラーメッセージをどのように取得するか、(b)正しい参照タイプをロードできるかどうか、他の人に回答チェックマークを付けていただければ幸いです。

0

でプログラムをロードするために作られました。古い2.0コンパイラがデフォルトで使用されている可能性があります。 (4.0がサポートされているかどうか、私は知りませんが、あなたはそれを必要としない)C#3.5のバージョンを有効にするため、以下のリンクをチェック:

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

でもある CompilerResultErrorsコレクションをチェック CompileAssemblyFromSource()メソッドから返されました。コンパイルに失敗しても例外は発生しません。コンパイルエラーを手動でチェックする必要があります。

+0

私はCompilerVersion設定を使ってみましたが、同じ結果を得ました。 GenerateInMemoryをfalseに設定しない限り、コンパイル時に例外がスローされます。しかし、たとえそれをfalseに設定したとしても、Errorsコレクションにはゼロエラーがあります。 – Bryant

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(); 
    } 
関連する問題