1

私は MVC アプリを作成しています。このアプリでは、ユーザーが使用するフィルターに基づいてオブジェクトのリストを取得する必要があります。

したがって、次のような文字列になる可能性があります。

*OBJNAME=[SWORD][OF][THOUSAND][TRUTHS]*OBJTYPE=[ARTEFACT]*OBJNUMBER=[28]*COST=[9]+<*POWER=[3]+>=*RATING=[4]+<*OWNER=[WRIGHT][STAN]*OBJSET=[WORLD OF WARCRAFT]*RARITY=[LEGENDARY]*ADDCOST=[6QGBA]*OBJCOLOR=[ALL]

すべての * は、DAL クラスで各属性を個別に識別できるように、文字列を作成するときに導入するタグです。

public List<ObjInfo> ListObjWithQryString(string _objQry)
{
    List<ObjInfo> listToReturn = new List<ObjInfo>();

    char[] firstDelimiters = {'*'};

    string[] parsedValues = _objQry.Split(firstDelimiters,
       StringSplitOptions.RemoveEmptyEntries);

    foreach (string parsedValue in parsedValues)
    {
       if (parsedValue.Contains("OBJNAME"))
       {
           // WRITE CODE HERE
       }
    }

    return listToReturn;
}

今私の問題は、各パラメーターが存在する場合と存在しない場合があるという事実に基づいているため、クエリ文字列が変更されます。特に、最終的に変更される可能性があるため、81 の可能性ごとに対処する必要はありません。

取得した値に応じてデータベースへのクエリを動的に作成し、探している値のみを返す方法はありますか?

* 編集 *

以下は、最終的に得られる可能性のある文字列の例です。

*OBJNAME=[SWORD][OF][THOUSAND][TRUTHS]

// Seeking all objects named Sword of a Thousand Truths

*OBJNAME=[SWORD][OF][THOUSAND][TRUTHS*OBJNUMBER=[28]*COST=[9]+<*POWER=[3]+>=*RATING=[4]+<RARITY=[LEGENDARY]*ADDCOST=[6QGBA]*OBJCOLOR=[ALL]

// Seeking all objects named Sword of a Thousand Truths with number 28 with cost lesser than 9 with power greater or equal to 3 with rating lesser than 4 with rarity Legendary with additional cost 6QGBA with all colors

*OBJNAME=[SWORD][OF][THOUSAND][TRUTHS]*OBJTYPE=[ARTEFACT]*OBJNUMBER=[28]*COST=[9]+<*POWER=[3]+>=*RATING=[4]+<*OWNER=[STAN]*OBJSET=[WORLD OF WARCRAFT]

// Seeking all objects named Sword of a Thousand Truths with type Artefact with number 28 with cost lesser than 9 with power greater or equal to 3 with owner Stan with objSet World of Warcraft

*ADDCOST=[6QGBA]*OBJCOLOR=[ALL]

// Seeking all objects with additional cost 6QGBA with all colors

*ADDCOST=[6QGBA]*OBJCOLOR=[BLUE][RED][PURPLE]

// Seeking all objects with additional cost 6QGBA with specific color Blue, Red, Purple

*OBJTYPE=[ARTEFACT]*POWER=[3]+>=

// Seeking all objects with type Artefact and power greater or equal to 3

したがって、文字列とは異なるタグを持つことになる可能性があることがわかります。必要に応じて、追加情報を貼り付けることができます。

* また*

これが私が現在自分のアプリを構築した方法であることを覚えておいてください。しかし、より良い方法があれば、どんな提案も受け入れます。

編集2

@I4V のおかげで、実際に値をグループ化する辞書があります。そう:

var dict = Regex.Matches(_cardQry, @"\*(\w+)=([^\*$]+)").Cast<Match>()
                            .ToDictionary(x => x.Groups[1].Value,
                                          x => string.Join(" ", x.Groups[2].Value.Split(new char[] {'[', ']'})));

辞書をくれます。最初のパラメーターがそこに渡された文字列を使用しforeachて辞書を調べると、次のようになります。

キー/値

OBJNAME= SWORD  OF  THOUSAND TRUTHS  
OBJTYPE= ARTIFACT 
OBJNUMBER= 28 
COST= 9 +>= //(small bug here, there should not be a "=" sign at the end, but it's not major)
POWER= 3 +<=
RATING= 4+<
OWNER= STAN
OBJSET= WORLD OF WARCRAFT
RARITY= LEGENDARY
ADDCOST= 4  W  G  U  G  R 
OBJCOLOR= ALL 

そして、このコード行で:

var whereCondition = "WHERE " + String.Join(" AND ", dict.Select(kv => kv.Key + "='" + kv.Value + "'"));

私は次のような文字列を使用することになります:

WHERE OBJNAME=' SWORD  OF  THOUSAND TRUTHS ' AND OBJTYPE=' ARTIFACT ' AND OBJNUMBER=' 28 ' AND COST=' 9 +<' AND POWER=' 3 +>' AND RATING=' 4 +<' AND OWNER=' STAN ' AND OBJSET='WORLD OF WARCRAFT ' AND RARITY=' LEGENDARY ' AND ADDCOST=' 4  W  G  U  G  R  ' AND OBJCOLOR=' ALL '

さて、問題は文字列を作成することではなく、それを使用してクエリ呼び出しを行う方法です。私はMVCアプリ、特にデータベース呼び出しに非常に慣れていません。私は通常、次のようにデータベース呼び出しを行いました。

var objQry = from o in m_DB.O
             where o.NAME == _nameProvided
             select o;

このようなクエリ呼び出しを行うために文字列を使用するにはどうすればよいですか?

4

1 に答える 1

1

入力文字列から辞書を作成できます。それを使った作業はより簡単になります。

string input = "*OBJNAME=[SWORD][OF][THOUSAND][TRUTHS]*OBJTYPE=[ARTEFACT]*OBJNUMBER=[28]*COST=[9]+<*POWER=[3]+>=*RATING=[4]+<*OWNER=[WRIGHT][STAN]*OBJSET=[RETURN TO RAVNICA]*RARITY=[LEGENDARY]*ADDCOST=[6QGBA]*OBJCOLOR=[ALL]";

var dict = input.Split(new char[]{'*'},StringSplitOptions.RemoveEmptyEntries)
             .Select(p => p.Split('='))
             .ToDictionary(kv => kv[0], 
                           kv => kv[1].Replace("[", "").Replace("]", " ").Trim());

または正規表現を使用する

var dict2 = Regex.Matches(input, @"\*(\w+)=([^\*$]+)").Cast<Match>()
            .ToDictionary(x => x.Groups[1].Value, 
                          x => String.Join(" ",x.Groups[2].Value.Split(new char[]{'[',']'},StringSplitOptions.RemoveEmptyEntries)));
于 2013-04-16T16:11:57.017 に答える