1

2つのカスタムクラスがあります。

最初のクラスには基本データが含まれています。

public class Request
{
    public Request(int lineID, string partNo, int qty, int reasonID, int typeID)
    {
        LineID = lineID;
        PartNo = partNo;
        Qty = qty;
        ReasonID = reasonID;
        TypeID = typeID;
    }
    public int LineID { get; private set; }
    public string PartNo { get; private set; }
    public int Qty { get; internal set; }
    public int ReasonID { get; private set; }
    public int TypeID { get; private set; }
}

2番目のクラスには、これらのRequestオブジェクトのリストが含まれ、次のような署名が付いています。

public class Requests : IEnumerable<Request>
{
    private List<Request> list;

    public Requests()
    {
        list = new List<Request>();
    }

    public int Add(Request item)
    {
        if (item != null)
        {
            foreach (var x in list.Where(r => 
              (r.LineID == item.LineID) &&
              (r.PartNo == item.PartNo) &&
              (r.ReasonID == item.ReasonID) &&
              (r.TypeID == item.TypeID)))
            {
                x.Qty += item.Qty;
                return list.IndexOf(x);
            }
            list.Add(item);
            return list.Count - 1;
        }
        return -1;
    }

    // other code 
}

コードをテストしていて、アイテムを追加すると新しいアイテムがリストに追加されますが、重複を見つけるためのLINQクエリが機能しません。

2つの同一のアイテムがリストに追加された場合、コードをスマートにして数量を更新するだけでよいのですが、機能していないようです。

誰かがLINQクエリの何が問題になっているのか教えてもらえますか?

4

3 に答える 3

3

誰かがLINQクエリの何が問題になっているのか教えてもらえますか?

理論的には問題ないように見えます。データが期待どおりに機能しない理由を見つけるには、データに関する詳細情報を知る必要があると思います。、、、の組み合わせはLineID、アイテムPartNoを一意ReasonIDTypeID区別しますか?は文字列なのでPartNo、値は大文字と小文字を区別しませんか(比較では大文字と小文字が区別されます)?

2つの同一のアイテムがリストに追加された場合、コードをスマートにして数量を更新するだけでよいのですが、機能していないようです。

このために、私は別のアプローチを提案します。タイプをオーバーライドEquals()することを検討してくださいRequest。次に、Addメソッドはリストにアイテムがすでに含まれているかどうかを確認し、含まれている場合は数量を増やし、含まれていない場合は追加します。

var idx = list.IndexOf(item);
if(idx != -1)
{
    list[idx].Qty += item.Qty;
}
else
{
    list.Add(item);
}
于 2012-06-14T16:21:32.460 に答える
2

これが使用するものであるため、実装を作成Requestします。IEquatable<Request>IndexOf

public bool Equals(Request other) {
    return other != null && (this.LineID == other.LineID) && (this.PartNo == other.PartNo) && (this.ReasonID == other.ReasonID) && (this.TypeID == other.TypeID);
}

それで:

public int Add(Request item) {
    if (item != null)
    {
        int ind = list.IndexOf(item);

        if (ind == -1)
        {
            list.Add(item);
            return list.Count - 1;
        }
        else
        {
            list[ind].Qty += item.Qty;
            return ind;
        }                
    }
    return -1;
}
于 2012-06-14T16:14:28.610 に答える
2

LINQクエリをマテリアライズすることでメソッドを変更できます。例えば:

public int Add(Request item) {
    if (item != null) {
      foreach (var x in list.Where(r => 
        (r.LineID == item.LineID) &&
        (r.PartNo == item.PartNo) &&
        (r.ReasonID == item.ReasonID) &&
        (r.TypeID == item.TypeID)
        ).ToList()) {
        x.Qty += item.Qty;
        return list.IndexOf(x);
      }
      list.Add(item);
      return list.Count - 1;
    }
    return -1;
  }

ただし、リクエストは一意である必要があるため、これを使用できます

public int Add(Request item)
{
    if (item != null)
    {
        var req = list.SingleOrDefault(r =>
                              (r.LineID == item.LineID) &&
                              (r.PartNo == item.PartNo) &&
                              (r.ReasonID == item.ReasonID) &&
                              (r.TypeID == item.TypeID)
            );
        if(req!=null)
        {
            req.Qty += item.Qty;
            return list.IndexOf(req);
        }
        list.Add(item);
        return list.Count - 1;
    }
    return -1;
}
于 2012-06-14T16:36:15.807 に答える