Уменьшить объем данных Ajax путем привязки к DataTable с вложенными объектами?
Кажется, есть много вопросов, связанных с привязкой к DataTable, но ни один из них я не смог бы затронуть в своей конкретной ситуации.
В настоящее время я привязываю ajax к списку таких объектов:
public class MyObject
{
public string Name { get; set; }
public string Something1{ get; set; }
public string Something2{ get; set; }
public string Something3 { get; set; }
public MyObjectMyObject2 { get; set; }
}
public class MyObject2
{
public string Color { get; set; }
public string Something4 { get; set; }
}
[GridAction]
public ActionResult GetData()
{
var data = QueryDatabaseAndInstantiateAListOfMyObjects();
return View(new GridModel(data));
}
И с таким видом
<%= Html.Telerik().Grid<MyObject>()
.DataBinding(dataBinding => dataBinding.Ajax().Select("GetData", new { action = "GetData" }))
.Name("Grid1")
.Columns(columns =>
{
columns.Bound(o => o.Name).Title("Name1");
columns.Bound(o => o.MyObject2.Color).Title("Color");
columns.Bound(o => o.Something1).Hidden(true);
columns.Bound(o => o.Something2).Hidden(true);
columns.Bound(o => o.Something3).Hidden(true);
columns.Bound(o => o.MyObject.Something4).Hidden(true);
})
%>
Это прекрасно работает и все, что я могу сортировать, группировать и все выше.
Моя ситуация такова: у меня много свойств в MyObject, и появляются некоторые крайние случаи, которые дают пару мегабайт ответных данных. Причина в том, что существует много скрытых столбцов, которые зависят от ситуации, и пользователь может щелкнуть правой кнопкой мыши, чтобы отобразить их. Проблема в том, что данные для всех этих дополнительных скрытых столбцов включаются в данные ответа, даже если они не используются, скажем так. И поскольку в любом случае происходит группировка, разгруппировка, отображение и скрытие столбцов для выборки данных, почему все дополнительные данные должны поставляться вместе с ними?
Если бы у меня могли быть только возвращенные данные, необходимые для заполнения видимых столбцов, и, скажем, пара, которую я мог бы как-то пометить с помощью пользовательского атрибута, это очень помогло бы сократить размер возвращаемых данных.
Поэтому я решил преобразовать мой список объектов в DataTable, для которого я затем мог бы условно добавить столбцы + данные и затем передать их в GridModel. Это работало до тех пор, пока не было сгруппировано по столбцу, который находится во вложенном объекте, таком как o.MyObject2.Color. Я сталкиваюсь с этим исключением:
Свойство с указанным именем: MyObject2.Color не может быть найдено для типа: System.Data.DataRowView
Я думаю, это имеет смысл, но как мне преодолеть это? Когда я использую Object Shredder, он устанавливает каждое свойство MyObject со свободной типизацией, такое как ["Name"] как строка и ["MyObject2"] как MyObject2. Но все прошлое ["MyObject2"] строго типизировано: (dataRow["MyObject2"] как MyObject2).Color. И это где-то над моей головой.
Есть ли другой способ преодолеть мою первоначальную проблему со всеми этими дополнительными данными, которые не используются? Или есть какой-нибудь совет с битом DataTable? Я также попытался преобразовать DataTable в IEnumerable без такой удачи. Серийный Json довольно пуст. Я также попытался сгладить все вложенные объекты, такие как наличие datarow["MyObject2.Color"] в качестве строки, но это приводит к ошибкам при обращении к этому столбцу в JavaScript, поэтому мне пришлось использовать разделитель подчеркивания ["MyObject2_Color"], но это действительно Винт связывания столбцов в пользовательском интерфейсе. Должен быть способ!
2 ответа
Я не вижу смысла возвращать ваш полный объект просто чтобы показать Color
а также Something4
, Попробуйте сгладить это. Примерно так, где вы просто назначаете значения Color
а также Something4
к свойствам модели.
public class MyObject
{
public string Name { get; set; }
public string Something1{ get; set; }
public string Something2{ get; set; }
public string Something3 { get; set; }
public string Something4 { get; set; }
public string Color { get; set; }
}
[GridAction]
public ActionResult GetData()
{
var data = QueryDatabaseAndInstantiateAListOfMyObjects();
data.Something4 = MyObject2.Something4;
data.Color = MyObject2.Color;
return View(new GridModel(data));
}
Это верный ответ, но я отдаю должное люцерне за эту идею.
Я продолжаю вместе с идеей DataTable, но использую геттеры, чтобы раскрыть каждое свойство вложенного объекта. Это немного замкнутый и хрупкий, но это работает!
public class MyObject
{
public string Name { get; set; }
public string Something1{ get; set; }
public string Something2{ get; set; }
public string Something3 { get; set; }
[ScriptIgnore()]
public MyObjectMyObject2 { get; set; }
public string Color { get { return this.MyObject2.Color; } }
public string Something4 { get { return this.MyObject2.Something4; } }
}
public class MyObject2
{
public string Color { get; set; }
public string Something4 { get; set; }
}