2

私のテーブルには、次のフィールドがあります。

public string CARD_MANA_CONVT { get; set; }

文字列として書かれた数値フィールドです。うん。時間の 95% で値が int であり、残りの 5% が X になるため、これを文字列にしました。

ユーザーが選択した値に基づいてクエリを作成する必要があります。問題は、値が高いか低いかを確認する必要があることです。

これが私のクエリです:

var cardsList = cardList.Where(_item => _item.CARD_MANA_CONVT > 5);

これを行う方法はありますか?

4

11 に答える 11

2

値の省略を として表現しようとしているようですX。タイプのNullable方がうまくいくかもしれません。タイプを からstringに変更しint?ます。

public int? CARD_MANA_CONVT { get; set; }

それで:

var cardsList = cardList.Where(_item => _item.CARD_MANA_CONVT.HasValue &&
                                        _item.CARD_MANA_CONVT > 5);
于 2013-07-25T19:08:42.630 に答える
2

Int.TryParse を使用できます

var cardsList = cardList.Where(_item => {
                           int conv;
                           return int.TryParse(_item.CARD_MANA_CONVT, out conv) && 
                             conv > 5;
                           });

X が >5 であると想定される場合

var cardsList = cardList.Where(_item => {
                           int conv;
                           return _item.CARD_MANA_CONVT == "X" || 
                                  (
                                  int.TryParse(_item.CARD_MANA_CONVT, out conv) && 
                                  conv > 5
                                  );
                           });

これによりクエリが読みにくくなることがわかった場合は、拡張メソッドに抽出できます。

public static class ManaHelper {
    public static bool IsGreaterThan(this string mana, int value, bool includeX) {

        if (mana == "X") return includeX;
        int manaValue;
        return int.TryParse(mana, out manaValue) && manaValue > value;
    }
}

次に、次のことができます。

var cardsList = cardList.Where(_item => _item.CARD_MANA_CONVT.IsGreaterThan(5,false));

または結果にX含める

var cardsList = cardList.Where(_item => _item.CARD_MANA_CONVT.IsGreaterThan(5,true));
于 2013-07-25T19:15:39.000 に答える
1

これはいくつかの可能な解決策の1つかもしれません

var cardsList = cardList.Where(_item => _item.CARD_MANA_CONVT != "X" && Convert.ToInt32(_item.CARD_MANA_CONVT) > 5);

「値は 95% の時間で int であり、残りの 5% は X になる」と述べているため、これ以上保護された句は含めません。

于 2013-07-25T19:27:43.710 に答える
1

そのはず

var cardsList = cardList.Where(_item => _item.CARD_MANA_CONVT != null && _item.CARD_MANA_CONVT > 5);

が代わりにCARD_MANA_CONVT宣言されている場合、動作するはずです。int?

于 2013-07-25T19:09:15.267 に答える
1

あなたのプログラムはマジック・ザ・ギャザリングに関係していると推測しているので、私の最初の提案は、点数で見たマナ コストが「X」のカードを -1 として扱い、それらを最初ではなく最後にソートする必要がある場合は、if を含めることです。カード A に CMC -1 がある場合、自動的に最後になるというステートメント (または、同じことを行うカスタム iComparer を作成できます)。とにかく、そこにあるものを使用すると、文字列の解析が1つのオプションになり、そのように実行できます(C#演算子のオーバーロード構文を覚えていないため、ここに構文エラーがある可能性があります):

 public bool operator_> (string b)
 {
    if (this.CARD_MANA_CONVT == 'X')
        return true;
    else 
        int a = int.Parse(this.CARD_MANA_CONVT);
    if (b == 'X')
        return false;
    else
        int b = int.Parse(b);
    return a>b;
 }

編集: オーバーロードを < から > に変更し、それを反映するようにメソッドを修正しました。

于 2013-07-25T19:13:36.560 に答える
1

あなたの質問のヘッダーは、>演算子を文字列で使用することについて話しています。現在のスレッド文化が影響を与える可能性があるため、グローバリゼーションと文字列比較について読むことをお勧めします。

IComparable<T>この場合、実装する必要があると思います。

public class Mana : IComparable<Mana>
    {
        private readonly string _value;

        public Mana(string value)
        {
            _value = value;             
        }

        public int CompareTo(Mana other)
        {
            if (Value == "X")
                return 1;
            if (other.Value == "X")
                return -1;
            return Convert.ToInt32(Value).CompareTo(Convert.ToInt32(other.Value));
        }
    }

注: 特に色に関心がある場合は、これは本番環境に対応しておらず、X を他の値と比較する方法を決定する必要があります。@Namfuakが示したように、必要に応じて演算子をオーバーロードできますが、マナは数値のように機能しないため、反対することをお勧めします。

Card次のようなメソッドを配置することを検討することもできます。

public Mana GetConvertedCost()
{
    var convertedValue = Value != "X" ? Value : "0";
    return new Mana(convertedValue);                
}
于 2013-07-25T19:14:25.237 に答える
1

これは、null ではなく、5 より大きい場合を識別します。

var cardsList = cardList.Where(_item =>
    _item.CARD_MANA_CONVT != null &&
    _item.CARD_MANA_CONVT.All(char.IsNumeric) &&
    Convert.ToInt32(_item.CARD_MANA_CONVT) > 5);

より多くのケースを識別する必要がある場合は、より多くのクエリを作成する必要があります。これらのクエリは本質的に線形であり、複数のデータ セットを返すことができないためです。たとえば、代わりに「X」を表示する必要がある場所を知る必要がある場合は、次のクエリが必要です。

var cardsListNulls = cardList.Where(_item => _item.CARD_MANA_CONVT == null);

そして、それらのリストを組み合わせることができます:

var list = cardsList.Concat(cardsListNulls);
于 2013-07-25T19:14:35.197 に答える
1

int にパースしようとするメソッドを書きます。

 public static int ParseToint(string text)
    {
        int value;
        if (int.TryParse(text, out value))
            return value;
        else return 0;
    }

彼らはあなたの表現でそれを呼び出すだけです

var cardsList = cardList.Where(_item => ParseToint(_item.CARD_MANA_CONVT) > 5);
于 2013-07-25T19:15:10.537 に答える
0

私は多くの方法を試しましたが、解決策を見つけました。実際に機能するこの投稿を使用してください: string.Compare()

于 2016-11-27T21:29:37.633 に答える
-3

これを試して

var cardsList = cardList.Where(_item => _item.CARD_MANA_CONVT.HasValue && Convert.ToInt32(C_item.CARD_MANA_CONVT) > 5);
于 2013-07-25T19:09:14.617 に答える