Вместо того, чтобы вручную анализировать весь ответ каждый раз, я бы посоветовал вам воспользоваться мощным API-интерфейсом, предоставленным нам компанией Apple, - Codable .
blockquote>Подробнее о кодируемом можно прочитать здесь: https://developer.apple.com/documentation/swift/codable
Вы можете определить ключи кодирования Вы хотите разобрать и получить готовые модели от Codable.
Пример кодирования:
Создайте свою модель соответственно
struct Root: Codable { let customAttributes: [CustomAttribute] enum CodingKeys: String, CodingKey { case customAttributes = "custom_attributes" } } struct CustomAttribute: Codable { let attributeCode: String let value: [Value] enum CodingKeys: String, CodingKey { case attributeCode = "attribute_code" case value } } struct Value: Codable { let color: [Color] } struct Color: Codable { let valueIndex, label, productSuperAttributeID, defaultLabel: String let storeLabel: String let useDefaultValue: Bool enum CodingKeys: String, CodingKey { case valueIndex = "value_index" case label case productSuperAttributeID = "product_super_attribute_id" case defaultLabel = "default_label" case storeLabel = "store_label" case useDefaultValue = "use_default_value" } }
Использование: [119 ]
Alamofire.request("http://adorableprojects.store/rest/V1/detailProduct/configurable-product").responseJSON { (responseData) -> Void in if((responseData.result.value) != nil) { let swiftyJsonVar = JSON(responseData.result.value!) let customAttributesResponse = swiftyJsonVar["custom_attributes"] do { // You can parse response with codable's here let data = try customAttributesResponse.rawData() let customAttributes = try JSONDecoder().decode([CustomAttribute].self, from:data) print(customAttributes) } catch { debugPrint("\(#function)--\(error)") } } }
Вы могли попытаться настроить Нетерпеливую Загрузку на этой объектной ассоциации. Что-то как:
var dlo = new DataLoadOptions();
// Configure eager loading
dlo.LoadWith<Question>(q => q.QuestionTags);
_context = new WhateverContext();
_context.LoadOptions = dlo;
Но Вы, возможно, должны осуществить рефакторинг свой код немного. В основном Вы говорите платформе выпускать SQL, чтобы вытянуть в более широком графе объектов, вместо того, чтобы ожидать, пока к объектной ассоциации не получают доступ (ленивая загрузка является значением по умолчанию).
Возможно, посмотрите (http://blog.codeville.net/2007/12/02/linq-to-sql-lazy-and-eager-loading-hiccups/). Другой Steven между прочим!
ToList () определенно сдерживает Вас. Необходимо сделать ToList () на целом запросе.
Другая вещь, что я думаю, что можно сделать, использовать, "позволяют". Я думаю в этом случае, это может создать задержанное выполнение и быть включено в дерево выражений, но YMMV.
from p in db.Questions
let Tags = (from t in p.QuestionTags
select t.Tag.Name)
select new Models.Question
{
Title = p.Title,
TagList = Tags
}
Это могло бы быть одним из случаев, где LINQ отдельно не достаточно. Вы полагали, что запись этой логики как UDF или SPROC и просто использование LINQ называет его? LINQ-SQL очень хорош в вызове любого (Платформа объекта не является настолько большой с UDFs).
Затем Вы могли сделать тег, объединяющийся в базе данных, и возвратить его как varchar, например. Существует прием TSQL для того, чтобы сделать это без курсора:
DECLARE @foo varchar(max)
SET @foo = ''
SELECT @foo = @foo + [SomeColumn] + ',' -- CSV
FROM [SomeTable]
WHERE -- some condition
(возможно, удаление запаздывающей запятой)
После выполнения этого, @foo
будет CSV значений - очень эффективный, если Вы возвратите одну строку. Не настолько большой, если Вы возвращаете несколько основных строк.
Я предполагаю, что проблема состоит в том, что необходимо назвать.ToList () для целого запроса также. Это возвратит целый набор в одном от дб.
В Вашем случае первая команда SQL возвращает только идентификаторы всех вопросов и затем, единственный вызов SQL происходит для каждого вопроса (во время повторения в цикле foreach) - посмотрите @x1 param.
Вы можете выполнять ленивые погрузки следующим образом:
from p in db.Questions
let Tags = GetTags(Questions.Id)
select new Models.Question
{
Title = p.Title,
TagList = LazyList<string>(Tags)
}
public IQueryable<string> GetTags(int questionId) {
from qt in db.QuestionTags
join t in db.Tags on qt.TagId equals t.Id
where qt.questionId = questionId
select t.Name
}
LazyList - это контейнер IQueryable, реализующий IList. Как только перечисляется свойство TagList, будет выполнен IQueryable, хранящийся внутри.
Класс LazyList был написан Rob Connery и может быть найден здесь: http://blog.wekeroad.com/blog/lazy-loading-with-the-lazylist/