EntityDataSource Null Update Pameters не помечены как измененные - PullRequest
2 голосов
/ 25 февраля 2011

Я использую EntityDataSource с приложением FormView на VB.NET. FormView содержит AjaxControlToolKit TabContains с несколькими вкладками. Из-за того, что каждая вкладка является контейнером именования, Bind не работает должным образом для обновления значений (как обнаружено при чтении других сообщений в stackoverflow). Вместо этого я должен объявить UpdateParameters на моем EntityDataSource. Пример разметки выглядит следующим образом:

<asp:FormView ID="fv" runat="server" DataSourceID="eds" DataKeyNames="ID">
<EditItemTemplate>  
    <asp:TabContainer ID="tc" runat="server">
        <asp:TabPanel ID="tp" runat="server" HeaderText="Tab 1">
            <ContentTemplate>
                <asp:TextBox ID="tbName" runat="server" Text='<%#Eval("Name") %>'></asp:TextBox>
            </ContentTemplate>
        </asp:TabPanel>
    </asp:TabContainer>
</EditItemTemplate> 
</asp:FormView>

<asp:EntityDataSource ID="eds" runat="server" ConnectionString="name=NDSEntities"
DefaultContainerName="NDSEntities" EnableFlattening="False" EntitySetName="Customers"
    Where="it.ID = @ID" EnableUpdate="true" EnableInsert="true">
    <WhereParameters>
        <asp:QueryStringParameter Name="ID" QueryStringField="ID" DbType="Guid" />
    </WhereParameters>
    <UpdateParameters>
        <asp:ControlParameter Name="Name" ControlID="fv$tc$tp$tbName" DbType="String" />
</UpdateParameters>
    <InsertParameters>
        <asp:ControlParameter Name="Name" ControlID="fv$tc$tp$tbName" DbType="String" />
</InsertParameters>
</EntityDataSource>

Это прекрасно работает, пока клиент не отредактирован и его имя не установлено в ничто (при условии, что в этом случае допустимо нулевое имя). Параметр Name UpdateParameter имеет значение Null, но для ObjectStateEntry не установлено изменение для свойств Null, даже если ранее для объекта было указано значение. Пока имя меняется на что-то отличное от Null, все обновляется правильно.

Я нашел обходной путь, добавив следующий код в событие Updating EntityDataSource.

Dim ose As ObjectStateEntry = context.ObjectStateManager.GetObjectStateEntry(action)
For Each p As Parameter In eds.UpdateParameters
  ose.SetModifiedProperty(p.Name)
Next

Это гарантирует, что каждому свойству в UpdateParameters присвоено измененное состояние. Это работает, но это похоже на взлом, и я вижу, что это вызывает проблемы в будущем. Могу ли я еще что-нибудь сделать?

1 Ответ

2 голосов
/ 25 февраля 2011

Есть ли у вас установленный режим параллелизма для рассматриваемой сущности? В зависимости от того, как вы на самом деле обновляете сущность (я не использовал EntityDataSource, но я предполагаю, что он внутренне использует метод ObjectContext.Attach), код, который создает инструкцию SQL, попытается обновить только те столбцы, которые на самом деле изменилось.

Обратите внимание на следующее:

void UpdatePersonEntity(int id, string firstName, string lastName)
{
    Person p = new Person { Id = id };
    this.Context.People.Attach(p);
    p.FirstName = firstName;
    p.LastName = lastName;

    this.Context.SaveChanges();
}

Если firstName или lastName имеют значение null, ObjectContext предполагает, что его исходное значение не было затронуто. Это может быть то, что вы должны изучить. Я прошу прощения, если это не поможет, но это может подтолкнуть вас в правильном направлении.

...