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类型可能会更好。将类型从 更改stringint?

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

这可能是一些可能的解决方案之一

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

我猜你的程序与万智牌有关,所以我的第一个建议是将总法术力费用“X”的卡视为-1,如果你需要它们最后而不是首先排序,请包含一个 if声明如果卡 A 有 CMC -1,它会自动排在最后(或者你可以编写一个自定义 iComparer 来做同样的事情)。无论如何,使用你所拥有的,解析字符串将是一种选择,并且可以这样做(我不记得 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

它应该是

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

您问题的标题谈到使用>带有字符串的运算符。我提醒您阅读全球化和字符串比较,因为当前的线程文化可能会产生影响。

我认为你需要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 所示,如果您愿意,您可以重载运算符,但我建议不要这样做,因为 mana 不像数字那样运行。

您可能还需要考虑将方法放在以下位置Card

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

这将确定它不为空且大于五的情况:

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 回答
1
int outValue = -1;    
var cardsList = cardList.Where(item => Int32.TryParse(item.CARD_MANA_CONVT, out outValue) && outValue > 5);

上述查询返回 cardList 中 CARD_MANA_CONVT 值大于 5 的所有元素,但它们不返回具有CARD_MANA_CONVT = "X"

于 2013-07-25T21:00:40.393 回答
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 回答