无法排序和删除LINQ C#中的重复项

时间:2019-04-04 08:59:29

标签: c# entity-framework linq sorting

我目前想对LINQ上的对象列表进行排序,如果建立的话,我需要在其中排序和删除重复项。如果我为自己的场景提供简单的示例,将会更容易。

这是我当前的列表(我已经对其进行了简化和排序):

{
  "data": [
    {
      "userActivityId": 17,
      "deviceId": 2,
      "name": "Apple Iphone X 2013 32 GB",
      "iconResource": "phone_apple_iphone_x.jpg"
    },
    {
      "userActivityId": 16,
      "deviceId": 1,
      "name": "Apple Iphone X 2013 16 GB",
      "iconResource": "phone_apple_iphone_x.jpg"
    },
    {
      "userActivityId": 15,
      "deviceId": 1,
      "name": "Apple Iphone X 2013 16 GB",
      "iconResource": "phone_apple_iphone_x.jpg"
    },
    {
      "userActivityId": 14,
      "deviceId": 2,
      "name": "Apple Iphone X 2013 32 GB",
      "iconResource": "phone_apple_iphone_x.jpg"
    },
  ]
}

预期结果

我真正想要的是

{
  "data": [
    {
      "userActivityId": 17,
      "deviceId": 2,
      "name": "Apple Iphone X 2013 32 GB",
      "iconResource": "phone_apple_iphone_x.jpg"
    },
    {
      "userActivityId": 16,
      "deviceId": 1,
      "name": "Apple Iphone X 2013 16 GB",
      "iconResource": "phone_apple_iphone_x.jpg"
    },
  ]
}

在这里我们可以看到userActivityId 1514被删除了,因为name已经存在。

因此,我们可以使用name进行唯一排序。

我尝试过的事情

首次尝试

这是排序功能的原始代码。

var data = new leapserverdbContext().TbUserActivity
            .OrderByDescending(id => id.UserActivityId)
            .Select(sel => new
            {
                sel.UserActivityId,
                sel.TbDevice.DeviceId,
                Name = sel.TbDevice.TbDeviceBrand.Name + " " + sel.TbDevice.Name +
                    " " + sel.TbDevice.TbDeviceYear.Year + " " + sel.TbDevice.TbDeviceSize.Size,
                    sel.TbDevice.IconResource                             
            })
            .ToList();

第二次尝试

我尝试放Distinct(),但是它不起作用,因为有userActivityId并且它是唯一的(因为递增)。

第三次尝试

我尝试删除userActivityId,以避免在Distinct()时被考虑,但是随后我的数据将不被排序。因为排序取决于 在userActivityId上。

第四次尝试

我尝试使用GroupBy (x => x.Name),因此根据唯一的名称进行焦点划分。 但它只是开始将它们分成如下所示的数组:

{
  "data": [
    [
      {
        "userActivityId": 16,
        "deviceId": 1,
        "name": "Apple Iphone X 2013 16 GB",
        "iconResource": "phone_apple_iphone_x.jpg"
      },
      {
        "userActivityId": 15,
        "deviceId": 1,
        "name": "Apple Iphone X 2013 16 GB",
        "iconResource": "phone_apple_iphone_x.jpg"
      }     
    ],
    [
      {
        "userActivityId": 17,
        "deviceId": 2,
        "name": "Apple Iphone X 2013 32 GB",
        "iconResource": "phone_apple_iphone_x.jpg"
      },
      {
        "userActivityId": 14,
        "deviceId": 2,
        "name": "Apple Iphone X 2013 32 GB",
        "iconResource": "phone_apple_iphone_x.jpg"
      }

    ]
  ]
}

现在,将根据其唯一的name对其进行排序和划分。但是布局完全不同。

在我看来,要做的就是获取第一个数组(因为这是最新的),但是如何合并并生成Expected Result(请参见上文)。

总有办法解决我的这个小问题吗?

2 个答案:

答案 0 :(得分:3)

除了像以前建议的那样使用EqualityComparer之外,您还可以将结果按名称属性分组,因为在这种情况下,您使用的是匿名类型。

var data = new leapserverdbContext().TbUserActivity
        .OrderByDescending(id => id.UserActivityId)
        .Select(sel => new
        {
            sel.UserActivityId,
            sel.TbDevice.DeviceId,
            Name = sel.TbDevice.TbDeviceBrand.Name + " " + sel.TbDevice.Name +
                " " + sel.TbDevice.TbDeviceYear.Year + " " + sel.TbDevice.TbDeviceSize.Size,
            sel.TbDevice.IconResource
        })
        .GroupBy(x => x.Name)
        .Select(g => g.First())
        .ToList();

答案 1 :(得分:2)

您可以创建一个平等比较器:

    public class ActivityComparer : IEqualityComparer<TbUserActivity>
    {
        public bool Equals(TbUserActivity x, TbUserActivity y)
        {
            if (x == null && y == null)
                return true;
            else if (x == null || y == null)
                return false;
            return x.name == y.name 
        }

        public int GetHashCode(TbUserActivity obj)
        {
            return obj.userActivityId;
        }
    }

然后:

result.Distinct(new ActivityComparer());