Как прочитать все коды с помощью запроса linq и сохранить в одной коллекции

#c# #linq

#c# #linq

Вопрос:

Я хочу прочитать весь код авторизации из RoleAmpLabelAdded в одном запросе linq в одной коллекции. я пишу ниже запрос для извлечения данных, а затем выполняю соединение строк.в настоящее время. Я делаю, как показано ниже. Пожалуйста, предложите мне какое-нибудь эффективное решение

  string strRoleCodesA = string.Join(",", request.ApplicationsAccess.CategoryAccessType
                                                           .SelectMany(c => c.BasicApplications.RoleAmpLabelAdded
                                                           .Select(t => t.AuthRoleCode)));

                          string  strRoleCodesB = string.Join(",", request.ApplicationsAccess.CategoryAccessType
                                                     .SelectMany(c => c.RegualrApplications.RoleAmpLabelAdded
                                                     .Select(t => t.AuthRoleCode)));

                            string strRoleCodesC = string.Join(",", request.ApplicationsAccess.CategoryAccessType
                                                       .SelectMany(c => c.OptionalSpecialApplications.RoleAmpLabelAdded
                                                       .Select(t => t.AuthRoleCode)));

                            strRoleCodesD = string.Concat(strRoleCodesA, strRoleCodesB, strRoleCodesC);
  

Я не хочу присоединяться к приведенной выше строке. Ниже приведена структура классов приведенного выше кода.

     public partial class ApplicationsAccess
{
    [JsonProperty("categoryAccessType")]
    public List<CategoryAccessTypeAMP> CategoryAccessType { get; set; }
}

public partial class CategoryAccessTypeAMP
{
    [JsonProperty("categoryCode")]
    public string CategoryCode { get; set; }

    [JsonProperty("basicApplications")]
    public Applications BasicApplications { get; set; }

    [JsonProperty("regualrApplications")]
    public Applications RegualrApplications { get; set; }

    [JsonProperty("optionalSpecialApplications")]
    public Applications OptionalSpecialApplications { get; set; }
}

public partial class Applications
{
    [JsonProperty("applictaionType")]
    public string ApplictaionType { get; set; }

    [JsonProperty("roleAmpLabelAdded")]
    public List<RoleAmpLabels> RoleAmpLabelAdded { get; set; }

    [JsonProperty("roleAmpLabelRemoved")]
    public List<RoleAmpLabels> RoleAmpLabelRemoved { get; set; }
}

public partial class RoleAmpLabels
{
    [JsonProperty("roleAMPLabel")]
    public string RoleAmpLabelRoleAmpLabel { get; set; }

    [JsonProperty("authRoleCode")]
    public string AuthRoleCode { get; set; }

    [JsonProperty("authRoleName")]
    public string AuthRoleName { get; set; }

    [JsonProperty("applications")]
    public List<Applications> Applications { get; set; }
}

public partial class Applications
{
    [JsonProperty("appId")]
    public string AppId { get; set; }

    [JsonProperty("appCode")]
    public string AppCode { get; set; }

    [JsonProperty("appName")]
    public string AppName { get; set; }
}
  

Классы загружаются из этой строки JSON :

 {
  "applicationsAccess": {
    "categoryAccessType": [
      {
        "categoryCode": "string",
        "basicApplications": {
          "applictaionType": "string",
          "roleAmpLabelAdded": [
            {
              "roleAMPLabel": "string",
              "authRoleCode": "string",
              "authRoleName": "string",
              "applications": [
                {
                  "appId": "string",
                  "appCode": "string",
                  "appName": "string"
                }
              ]
            }
          ],
          "roleAmpLabelRemoved": [
            {
              "roleAMPLabel": "string",
              "authRoleCode": "string",
              "authRoleName": "string",
              "applications": [
                {
                  "appId": "string",
                  "appCode": "string",
                  "appName": "string"
                }
              ]
            }
          ]
        },
        "regualrApplications": {
          "applictaionType": "string",
          "roleAmpLabelAdded": [
            {
              "roleAMPLabel": "string",
              "authRoleCode": "string",
              "authRoleName": "string",
              "applications": [
                {
                  "appId": "string",
                  "appCode": "string",
                  "appName": "string"
                }
              ]
            }
          ],
          "roleAmpLabelRemoved": [
            {
              "roleAMPLabel": "string",
              "authRoleCode": "string",
              "authRoleName": "string",
              "applications": [
                {
                  "appId": "string",
                  "appCode": "string",
                  "appName": "string"
                }
              ]
            }
          ]
        },
        "optionalSpecialApplications": {
          "applictaionType": "optionalSpecialApplications",
          "roleAmpLabelAdded": [
            {
              "roleAMPLabel": "string",
              "authRoleCode": "string",
              "authRoleName": "string",
              "applications": [
                {
                  "appId": "string",
                  "appCode": "string",
                  "appName": "string"
                }
              ]
            }
          ],
          "roleAmpLabelRemoved": [
            {
              "roleAMPLabel": "string",
              "authRoleCode": "string",
              "authRoleName": "string",
              "applications": [
                {
                  "appId": "string",
                  "appCode": "string",
                  "appName": "string"
                }
              ]
            }
          ]
        }
      }
    ]
  }
}
  

Комментарии:

1. Вы можете комбинировать несколько перечисляемых с Union too, устраняя необходимость в трех String.Join и одной конкатенации

2. Объединение @PanagiotisKanavos удаляет дубликаты, этот способ этого не делает. Я считаю, что это больше Concat , чем Union

3. Итак, у RoleAmpLabels есть приложения, у RoleAmpLabels есть приложения… Насколько глубоко это происходит?

4. @CaiusJard можно использовать Concat вместо Union . Однако рекурсивное отношение является реальной проблемой. Это можно решить с помощью метода итератора, но это определенно не так просто, как написать один запрос LINQ

5. Поскольку классы берутся из строки JSON, можно использовать JObject.Parse или JArray.Parse для анализа всей строки и использовать путь JSON для извлечения всех AuthRoleCode элементов, например o.SelectToken("$..authRolecode")

Ответ №1:

Итак, если вы сделаете это:

 request.ApplicationsAccess.CategoryAccessType
  .SelectMany(c => new[] { c.BasicApplications, c.RegualrApplications, c.OptionalSpecialApplications})
  

SelectMany сведет «массив приложений» в единый список всех приложений с их подсписками List

Затем вы добавляете это:

   .SelectMany(a => a.RoleAmpLabelAdded)
  

Он позволяет получить все метки ролей во всех списках меток ролей во всех приложениях, сведенных в единый список меток ролей, чтобы затем вы могли:

   .Select(r => r.AuthRoleCode)
  

Это IEnumerable<string> то, что может быть передано прямо string.Join
.Выберите(t => t.AuthRoleCode)));


Было бы проще рассуждать, если бы вы изменили имена своих классов, чтобы они соответствовали соглашению C # о единственном числе, а имена ваших свойств были множественными (если они представляют собой коллекцию).

 List<RoleAmpLabels> RoleAmpLabelAdded
  

Лучше записывается как один из:

 List<RoleAmpLabel> RoleAmpLabelsAdded
List<RoleAmpLabel> AddedRoleAmpLabels //my preference
  

Если вы создаете класс, представляющий собой коллекцию, единственной целью которого является создание коллекции, затем добавьте к нему «Collection», например DataRowCollection . Если у вас есть обычный класс, который имеет кратные значения какого-либо другого класса, то назовите свойство множественным числом

 Dealership{
  List<Car> CarsForSale
  List<Car> CarsInForRepair
}
  

Ответ №2:

Поскольку классы берутся из строки JSON, можно использовать JObject.Parse для анализа всей строки и использовать путь JSON для извлечения всех элементов AuthRoleCode, например :

 var o=JObject.Parse(json);
var codes=o.SelectTokens("$..authRoleCode").Select(s=>(string)s).ToArray();
  

Приведение необходимо для извлечения значений объектов JToken, возвращаемых SelectToken .

Это может быть преобразовано в список, разделенный запятыми String.Join() , например ;

 var codes=o.SelectTokens("$..authRoleCode");
var csv=String.Join(",",codes);
  

В этом случае приведение не требуется, поскольку String.Join вызывает ToString() метод каждого элемента.

Выполнение этого кода с помощью JSON вопроса возвращает :

 string,string,string,string,string,string