Нулевые обновления Pameters EntityDataSource не помечаются как измененные

Я использую EntityDataSource с FormView в приложении VB.NET. FormView содержит AjaxControlToolKit TabContains с несколькими вкладками. Из-за того, что каждая вкладка является контейнером именования, Bind не работает должным образом для обновления значений (как обнаружено при чтении других сообщений в stackru). Вместо этого я должен объявить 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, даже если ранее для Entity было указано значение. Пока имя изменено на что-то отличное от 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 ответ

Есть ли у вас установленный режим параллелизма для рассматриваемого объекта? В зависимости от того, как вы на самом деле обновляете сущность (я не использовал 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 предполагает, что его исходное значение не было затронуто. Это может быть то, что вы должны посмотреть. Я извиняюсь, если это не поможет, но это может подтолкнуть вас в правильном направлении.

Другие вопросы по тегам