【问题标题】:LINQ Query Fails to identify duplicatesLINQ 查询无法识别重复项
【发布时间】:2012-06-14 15:59:42
【问题描述】:

我有两个自定义类。

第一类包含基本数据:

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; }
}

第二个类包含这些Request对象的List,其签名如下:

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 查询有什么问题吗?

【问题讨论】:

  • 什么是RequestId?它没有在你的类中定义。
  • 不是答案,但使用 foreach 毫无意义,因为您在第一次迭代时返回。
  • 我会让Request实现IEquatable,并使用list.Contains(item)...
  • @jp2code,但这似乎不是 Web 应用程序的问题。正如 Jon 所建议的那样,您不能创建一个简单的控制台应用程序来调用 Add 方法并以这种方式传递一个副本并复制它吗?如果是这样,您可以发布该代码,我们可以尝试一下。

标签: c# visual-studio-2010 linq


【解决方案1】:

有人能告诉我 LINQ 查询有什么问题吗?

理论上看起来还可以。我认为我们需要了解有关您的数据的更多信息,以便能够找出为什么它没有按您的预期工作。 LineIDPartNoReasonIDTypeID 的组合是否唯一区分一个项目?由于PartNo 是一个字符串,这些值是否不区分大小写(您的比较区分大小写)?

如果将 2 个相同的项目添加到列表中,我希望我的代码足够聪明,可以简单地更新数量,但它似乎不起作用。

为此,我建议采用不同的方法。考虑在您的 Request 类型上覆盖 Equals()。然后你的Add 方法可以检查列表是否已经包含该项目,如果是则增加数量,如果不是则添加它:

var idx = list.IndexOf(item);
if(idx != -1)
{
    list[idx].Qty += item.Qty;
}
else
{
    list.Add(item);
}

【讨论】:

    【解决方案2】:

    使Request实现IEquatable&lt;Request&gt;,因为this is what IndexOf uses

    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;
    }
    

    【讨论】:

      【解决方案3】:

      您可以通过具体化 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;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-03
        相关资源
        最近更新 更多