2016-06-12 75 views
0

基本的には、特定のデータセットが必要なページがあります。 SQLはこのために遅くなるので、私の最初の考えは、Datatableがすでに設定されており、linqを使用してそこから選択することです。C#他のアプリケーション、asp Webサイトからインメモリオブジェクト(DataTable)にアクセスする方法

実行可能なハウスを他のアプリケーションからアクセスできるデータテーブルにするにはどうすればよいですか?また、Datatableは自分のデータに最も適した構造ですか?データは、基本的に400k行×6列です。

+0

キャッシングはどうですか? – Shaharyar

+0

@Shaharyarすべてがテーブルにあります。私は正直なところ、私が何を探しているのかを100%確信していません。メモリファイルについて考えましたが、それは欠点です。 – JL1

+0

実際には、オブジェクトはです。しかし、RDBMSのようなシナリオが遅すぎると繰り返しデータをすばやく選択したい場合は、RedisなどのコードとDBの間にキャッシングレイヤーを構築してください。 – Shaharyar

答えて

0

もう1つ(もっと良いと思いますが)アプローチはMarshalByRefObjectです。この方法では、オブジェクト(実際にはオブジェクトへのプロキシ)をAppDomainの間で渡すことができるので、シリアライゼーションはまったく必要ありません。

は対象

MSDN documentationをチェックアウトして、これは私も心の中で異なる目的で、数年前に開発された実際の例です。これはカスタムWebサーバーで、更新が利用可能なときにはジョブを中断することなく、自分自身を更新する必要がありました。だからシャドウコピーが目標でしたが、あなたのシナリオではMarshalByRefのオブジェクトを使用するのが適切であると思います。私が覚えていたよう

public void Boot() 
    { 
     if (KernelPartition != null) 
     { 
      throw new InvalidOperationException("Kernel partition already exists."); 
     } 

     Log.TraceEvent(TraceEventType.Verbose, 0, "Initiating startup sequence..."); 
     KernelPartition = AppDomain.CreateDomain("Kernel", null, new AppDomainSetup() { ApplicationName = "krnl", ShadowCopyFiles = "true" }); 
     KernelPartition.DomainUnload += KernelPartition_DomainUnload; 

     string engineClassName = null; 
     string engineAssemblyName = null; 

     try 
     { 
      var engineTypeId = ConfigurationManager.AppSettings["engineTypeId"]; 
      engineClassName = engineTypeId.Split(',')[0].Trim(); 
      engineAssemblyName = engineTypeId.Substring(engineClassName.Length + 1).Trim(); 
     } 
     catch (Exception) 
     { 
      Log.TraceEvent(TraceEventType.Verbose, 0, "Configuration errors detected. Attempting defaults..."); 
      engineClassName = "Contoso.Kernel.Turbine"; 
      engineAssemblyName = "Contoso.Kernel"; 
     } 

     try 
     { 
      // FOCUS ON THE NEXT LINE 
      KernelTurbine = (ITcsKernel)KernelPartition.CreateInstanceAndUnwrap(engineAssemblyName, engineClassName); 
      Log.TraceEvent(TraceEventType.Verbose, 0, "Kernel connection established."); 
     } 
     catch (Exception ex) 
     { 
      Log.TraceEvent(TraceEventType.Verbose, 0, "Failed to establish communication channel with the kernel with the following exception:\n{0}", ex.ToString()); 
     } 

     if (KernelTurbine == null) 
     { 
      InitializeRestart(); 
     } 
     else 
     { 
      try 
      { 
       Start(); 
       Log.TraceEvent(TraceEventType.Verbose, 0, "Startup sequence completed."); 
       KernelTurbine.RebootDelegate = Reboot; 
       DisposeRestartSecond(); 
      } 
      catch (Exception ex) 
      { 
       string message = string.Format("The startup sequence failed with the following exception:{0}{1}", Environment.NewLine, ex.ToString()); 
       Log.TraceEvent(TraceEventType.Error, 0, message); 

       InitializeRestart(); 
      } 
     } 
    } 

は、あなたがCreateInstanceAndUnwrap()することにより、他のAppDomainでオブジェクトを作成します。このオブジェクトはMarshalByRefObjectを継承する必要があります。したがって、それを継承し、内部でDataTableを使用するクラスを作成してください。

ここから対応していただければ幸いです。私は本当に詳細を覚えていませんが、私はあなたが必要な場合はさらに手伝っていきます。

+0

もう一度Bozhidarありがとう - この1つは、例を見つけるのは本当に難しいです – JL1

+0

多分私は何をしようとすることはできません。 1つのアプリケーションですべてをメモリに保持し、次に 'x'だけを返すオブジェクトを照会します。問題はSQLがちょっと遅すぎる – JL1

+0

Bozhidar - 私はちょっとこれをやってみましょう。私はフォローアップします:) – JL1

1

System.IO.MemoryMappedFilesはあなたが探しているものです。 データテーブルを初期化し、WriteXml()を使用してシリアル化することができます。 その後、System.IO.MemoryMappedFiles.CreateFromFile()メソッドを呼び出して、そのファイルをメモリにマップします。

次に、複数のプロセスからファイルにアクセスして、そのファイルを処理することができます。 など。あなたはおよそMemoryMappedFileshere

  • これは、.NET 4.0にし、上のなんとかですあなたはより多くの情報を見つけることができReadXml() を呼び出すことによって、別のプロセスでのデータテーブルに似ていることができます!
+0

Bozhidar - 私はWriteXMLを気にしません)? – JL1

+0

また、冗長性の種類ではありませんか?だから、私はデータテーブルを作成し、次にXMLファイルを作成してから、XMLファイルを保存してクラスをシリアライズしてからxmlファイルをデータテーブルに読み戻します。 – JL1

+0

@ JoshuaLong - 他にデータテーブルにアクセスする方法を想像できません。これは、 'MemoryMappedFiles'と呼ばれます - あなたはファイルになるために何とかあなたのデータをシリアル化する必要があります。 'WriteXml()'と 'ReadXml()'はすぐに使えます。しかし、バイナリのシリアライゼーションを実装してより高速にすることができます... –

関連する問題