Я нахожу три способа решения (некоторых) ваших проблем с помощью C # и способ расширить некоторые из этих подходов с помощью инструментов Visual Studio.
Анонимные типы
ASP.NET может привязывать данные к анонимным типам :
DataGrid.DataSource = GetAllUsers().
.AsQueryable()
.Select(u => new { User = u, FullName = GetFullName(u) });
DataGrid.DataBind()
Анонимный тип может по-прежнему обеспечивать легкий доступ к исходному типу (в этом примере через свойство User
). Это упростит привязку данных относительно (с использованием <asp:TemplateField>
), и вы переместили сложную логику в отдельный метод, который работает с объектом User
.
<%# Eval("User.FirstName") %>
<%# Eval("User.LastName") %>
<%# Eval("FullName") %>
Синтаксис привязки данных должен быть помещен в ItemTemplate
из <asp:TemplateField>
, но я для краткости опустил этот код. Конечно, последнее свойство также может быть отображено с помощью <asp:BoundField>
:
<asp:BoundField DataField="FullName" />
Обратите внимание, что вам не нужно сопоставлять каждое свойство исходного типа в анонимном типе, вы можете просто сопоставить одно свойство с исходным объектом. Недостаток (только?) Заключается в том, что вы больше не можете использовать <asp:BoundField>
для этих свойств, но вы должны использовать <asp:TemplateField>
.
Методы расширения
Чтобы дополнить этот подход, вы можете использовать методы расширения , чтобы «прикрепить» методы к классу, даже если у вас нет доступа к классу «source»:
public static class UserExtensions
{
public static string GetFullName(this User user)
{
return user.FirstName + " " + user.LastName;
}
}
Для привязки данных мы должны использовать <asp:TemplateField>
:
<%# Eval("User.FirstName") %>
<%# Eval("User.LastName") %>
<%# (Container.DataItem as User).GetFullName() %>
Частичные занятия
Другой вариант, доступный начиная с C # 2.0, заключается в написании частичного класса , но только если исходный класс также объявлен частичным и объявлен в вашем проекте (части того же модуля). Этот подход полезен, если класс User
создается с помощью инструмента, например, если вы используете какой-либо инструмент автоматического сопоставления баз данных в вашем проекте.
public partial class User
{
public string FullName
{
get { return this.FirstName + " " + this.LastName; }
}
}
Для привязки данных мы теперь возвращаемся к использованию '':
<asp:BoundField DataField="FirstName" />
<asp:BoundField DataField="LastName" />
<asp:BoundField DataField="FullName" />
Это все возможности компилятора C # и среды выполнения .NET, поэтому они относятся к категории методов вместо фреймворков. Конечно, базовое наследование также может быть использовано, но оно может быть неприменимо в вашей ситуации?
Текстовые шаблоны T4
Если у вас есть особые потребности в том, как должен выглядеть класс с привязкой к данным, но вы не можете использовать ни один из описанных выше подходов, вы всегда можете взглянуть на T4-шаблоны в Visual Studio. (Они работают в проектах веб-приложений ASP.NET, но не в проектах веб-сайтов ASP.NET.)
С помощью этих шаблонов вы можете генерировать код во время разработки, например, для создания поверхностного, неполного класса UserViewModel
, который прозрачно отображает все свойства во внутренний объект User. Затем, используя подход с частичным классом, вы можете добавить дополнительные свойства и методы к этому типу, используя другое частичное объявление класса в файле .cs, и просто привязать данные к вашему UserViewModel
:
DataGrid.DataSource = GetAllUsers().
.AsQueryable()
.Select(u => new UserViewModel(u));
DataGrid.DataBind()
Привязка данных снова становится прямой, используя <asp:BoundField>
:
<asp:BoundField DataField="FirstName" />
<asp:BoundField DataField="LastName" />
<asp:BoundField DataField="FullName" />
Используя шаблоны T4, вы можете автоматически сгенерировать эти пользовательские классы моделей представлений для всех типов ваших доменов. При использовании отражения в T4 есть предостережения: