#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
. Однако рекурсивное отношение является реальной проблемой. Это можно решить с помощью метода итератора, но это определенно не так просто, как написать один запрос LINQ5. Поскольку классы берутся из строки 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