Возможно ли иметь редактируемый DetailsView для объектов сущности с подклассами? - PullRequest
2 голосов
/ 31 января 2012

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

public class Gizmo : EntityObject { ... }
public class SpecialGizmo : Gizmo { ... }

На странице ASP.NET пользователь выбирает Gizmo в списке (GridView), а затем детали Gizmo представляются в DetailsView. Цель состоит в том, чтобы пользователь мог просматривать и редактировать подробности.

Вот соответствующий DetailsView и связанный с ним EntityDataSource:

<asp:DetailsView ID="GizmosDetailsView" DataSourceID="dsGizmoDetails"
    AutoGenerateEditButton="True" AutoGenerateInsertButton="True"
    AutoGenerateRows="False" DataKeyNames="GizmoId" runat="server">
    <Fields>
        <asp:BoundField DataField="GizmoId" HeaderText="GizmoId" ReadOnly="True" SortExpression="GizmoId" />
        <asp:BoundField DataField="Description" HeaderText="Description" SortExpression="Description" />
        <!-- ... etc. --->
    </Fields>
</asp:DetailsView>

<asp:EntityDataSource ID="dsGizmoDetails" runat="server" ConnectionString="[...]"
    DefaultContainerName="[...]" EnableFlattening="False" EnableUpdate="True"
    Where="it.[GizmoId] = @GizmoId">
    <WhereParameters>
        <asp:ControlParameter ControlID="gvwGizmos" Name="GizmoId" PropertyName="SelectedValue" Type="Int64" />
    </WhereParameters>
</asp:EntityDataSource>

Вышеприведенное не выполняется со следующим исключением:

InvalidOperationException: Должны быть определены либо CommandText, либо EntitySetName.

Это понятно. Однако оба представленных варианта что-то ломают:

  • Если я добавлю EntitySetName="Gizmo", то будут представлены только сущности фактического типа Gizmo. Если выбрано SpecialGizmo, DetailsView будет пустым.

  • Если я добавлю атрибут CommandText (или Select), то DetailsView больше не будет поддерживать обновление данных. Работающая кнопка «Изменить» (которая отображает пользовательский интерфейс редактирования) есть, но затем щелкнуть «Обновить» после внесения изменений просто ничего не делает.

Есть ли правильное решение этой дилеммы?

1 Ответ

1 голос
/ 01 февраля 2012

Я решил это с помощью следующего хака:

  • Укажите CommandText в источнике данных, что делает DetailsView неспособным автоматически обновлять данные, но обновлениеПользовательский интерфейс все еще доступен.

  • Установите для события DetailsView s OnItemUpdating что-то вроде этого:

    protected void GizmoDetailsView_Updating(object sender,
            DetailsViewUpdateEventArgs e)
    {
        db.ExecuteStoreCommand(/* use e.Keys["GizmoId"] and e.NewValues */);
        db.SaveChanges();
    
        // manually set the DetailsView back to read-only mode
        GizmoDetailsView.ChangeMode(DetailsViewMode.ReadOnly);
    
        // need to cancel the event, as otherwise we get the following exception:
        // InvalidOperationException: Update is disabled for this control.
        e.Cancel = true;
    }
    

Недостаток этого решения: другие элементы управления на странице, основанные на данных, которые обновляются таким образом, не обновляются до тех пор, пока пользователь не перезагрузит страницу вручную.

...