1

HH:MMデータベースには、時間を形式で含む列がいくつかあります。このような単純な式があれば11:00 - 12:00、C# で as と呼ばれる拡張メソッドを簡単に作成し、SubtractTime実行時に引数を渡すことができます。たとえば、数式をデータベースに保存します。

Condition                     Value
ExamTimeRemaing > 10:00       SubtractTime(Original,Remaining)     

上記の場合、実行時にリフレクションを使用して関数を呼び出すことができますSubtractTimeが、私の問題はこれです。式が次のように複雑になった場合はどうなりますか。

10:00 + 12:00 * 00:02 - 10:11

そのような式を解析するにはどうすればよいですか? 時間をティックに変換してから に変換する拡張機能が既にあるので、コーディングの助けは必要ありませんHH:MM。これは設計上の問題です。ルール エンジンを効率的に作成できるように、スケーラブルなソリューションが必要です。

4

3 に答える 3

0

それを文字列として保存し、演算子を見つけます。結果を正しい順序で解析および計算する再帰関数 ParseAndCalc(string input) を作成します。このようなもの:

double ParseAndCalc(string input)
{
    string[] sub;
    double result = 0;
    if(input.Contains("+"))
    {
        sub = input.Split('+');
        foreach(string substring in sub)
        {
            result += ParseAndCalc(substring);
        }
    }
    else if (input.Contains("-"))
    {
        sub = input.Split('-');
        foreach(string substring in sub)
        {
            result -= ParseAndCalc(substring);
        }
    }
    else if (input.Contains("*"))
    {
        sub = input.Split('*');
        foreach(string substring in sub)
        {
            result *= ParseAndCalc(substring);
        }
    }
    else if (input.Contains("/"))
    {
        sub = input.Split('/');
        foreach(string substring in sub)
        {
            double parsed = ParseAndCalc(substring);
            if(parsed != 0)
            {
                result /= ParseAndCalc(substring);
            }
            else
            {
                // Error
            }
        }
    }
    return result;
}
于 2014-02-24T09:43:56.397 に答える
0

ここでの回答は、これを十分に行う方法を示しています。あなたがこれを試みることにした場合、私はおそらくANTLRルートを自分で選択するでしょう.

そうは言っても、なぜあなたがこれをやりたいのかを真剣に考えます。あなたは「ルールエンジン」を構築していると述べました。このことから、一連のビジネス ロジックを "ルール" として保存し、"ルール エンジン" にこれを読み取らせて、いくつかのデータに適用させたいデータベースまたは何かがあると仮定します。この一環として、ある種の式パーサーで特定の種類のルールを解析および評価できるようにする必要があります。

このような設計を検討する際に、ルールの解析と実行の問題を混同しないように注意します。XML、JSON、またはお気に入りのコンテンツ形式でルールをエンコードできます。そうすれば、パーサーを書く必要はまったくありません。式を評価するだけです。

var myRule = [
  { $value: '10:00' },
  { $add: '12:00' },
  { $multiply: 2 },
  { $subtract: '10:11' }
]
于 2014-02-26T19:11:33.167 に答える
0

まず、開発と保守のオーバーヘッドを考慮する必要があります。Antlr などを使用して式パーサーを作成するのは絶対にばかげています。代わりに、Jurassic などの JavaScript エンジンやその他の .NET ベースの単純な JavaScript エンジンなどの既製のソリューションを使用します。

SQL ストアド プロシージャ/ユーザー定義関数

また、ルールがデータベース自体に格納されている場合は、パーサーを作成する代わりに、SQL 自体の機能を使用して式を解析および評価できます。SQL 式を動的に作成し、パラメーターを渡すことができます。または、十分にテストされ、よく知られており、スケーラブルであり、データベースのコンテキスト内にとどまるストアドプロシージャまたはユーザー定義関数を作成します。

オープン ソース .NET JavaScript エンジン

数式を JavaScript 形式でデータベースに保存することもできます。まず、JavaScript はよく知られており、よく理解されており、複雑な式を処理できます。豊富な言語機能を提供するだけでなく、数式内で既存の JavaScript ライブラリを引き続き使用できる、無料で安定した JavaScript エンジンが多数あります。たとえば、将来 Base64 が必要になった場合、単純に github から Base64 を取得して JavaScript に入れることができます。

C# コンパイラ

CSharpCompilerProvider クラスは、C# ソースをアセンブリにコンパイルする方法を提供します。テキスト テンプレートを使用してソース ファイルを作成し、アセンブリをコンパイルして SQL に格納し、式を呼び出す必要がある場合は、フェッチすることができます。コンパイルされたバージョンをロードし、Assembly.Loadいくつかのインターフェイスを持つ解析済みクラスを作成し、そのメソッドを呼び出します。.NET がコンパイルされ、アセンブリが提供されます。アセンブリは、.NET としてデータベースに保存できますvarbinary(max)

于 2014-02-26T08:04:42.357 に答える