Нулевые значения в сущности, когда событие удаления источника данных - PullRequest
1 голос
/ 27 сентября 2011

В настоящее время я использую Entity Framework, и у меня есть Gridview, отображающий список записей из базы данных. У меня есть кнопка «Удалить», которая использует команду «Удалить». Каждая запись имеет файл на сервере, связанный с ним, поэтому, когда источник данных вызывает событие удаления, я хочу получить имя файла и удалить файл с сервера. Странно то, что в моем событии ds_Deleting некоторые значения в сущности равны нулю. Я не могу понять, почему.

Код для моей кнопки «Удалить» в виде сетки следующий:

<asp:TemplateField HeaderText="Remove">
    <ItemTemplate>
        <asp:Button ID="btnRemove" runat="server" Text="Remove" CssClass="button_default" CommandName="Delete" OnClientClick="return confirm('Deleting this contract will also delete the file from the server. Continue?')" />
     </ItemTemplate>
 </asp:TemplateField>

Событие OnDeleting в коде позади выглядит следующим образом:

protected void dsContracts_Deleting(object sender, EntityDataSourceChangingEventArgs e)
{
    ipiModel.Contract contract = (ipiModel.Contract)e.Entity;

    File.Delete(Path.Combine(ConfigurationManager.AppSettings["ContractUploadPath"], contract.FileName));
}

Каждый раз, когда значение contract.FileName равно нулю, даже если оно правильно отображается в GridView. Любая помощь приветствуется. Спасибо!

Ответы [ 3 ]

3 голосов
/ 27 сентября 2011

Мне удалось выяснить это и я решил записать это здесь на случай, если у кого-то еще возникнет такая же проблема. Я проверил документацию на MSDN для события удаления источника данных объекта (который может быть найден здесь ), и это сказало

Свойство Entity объекта EntityDataSourceChangingEventArgs используется для доступа к удаляемому объекту. Свойства этого объекта могут быть не полностью установлены. Должны быть установлены только те свойства, которые необходимы для идентификации объекта.

Так вот почему я получаю нулевые значения. Решение, которое я придумал, возможно, не идеальное, но оно работает. Я понял, что первичный ключ ContractID всегда имел значение, поэтому я использовал его для извлечения записи из базы данных. Вот мой код:

protected void dsContracts_Deleting1(object sender, EntityDataSourceChangingEventArgs e)
{
    ipiModel.Contract ct = (ipiModel.Contract)e.Entity;

    using (var db = new ipiModel.ipiEntities())
    {
        var contract = db.Contracts.Where(c => c.ContractID == ct.ContractID).Single();

        File.Delete(Path.Combine(ConfigurationManager.AppSettings["ContractUploadPath"], contract.FileName));
    }
}
1 голос
/ 20 марта 2012

Испытав это на странице динамического списка данных ASP.NET и учитывая, что, по-видимому, существует ошибка с внешними ключами varchar (я считаю, что это принято Microsoft), любое решение будет чем-то вроде обходного пути (хак).

Чтобы обойти нулевые значения для столбцов таблицы со значениями по умолчанию (например, madeDate, CreatedBy и т. Д.), Я в итоге установил значения по умолчанию в конструкторе частичного класса для соответствующей сущности.

После того, как приведенная выше информация дала понять, что загружены только столбцы, необходимые для уникальной идентификации объекта, я обнаружил, что добавление другого значения «по умолчанию» для столбца проблемы (внешнего ключа) устранило мою проблему - то есть, потому что я не есть ли каскадное удаление или что-то еще, первичного ключа объекта достаточно, чтобы выполнить удаление, и это другая обработка, которая проверяет нулевые значения во внешнем ключе (varchar) - поэтому я просто устанавливаю для этого столбца значение String.Empty в и значение по умолчанию, которое я установил, игнорируется ...

, например

public partial class MyEntity
{

    public MyEntity()
    {
        CreatedDate = Datetime.Now;
        //Other default stuff
        MyProblemVarcharForeignKeyField = String.Empty;
    }
}

и вуаля!

0 голосов
/ 27 февраля 2012

Все, что вам нужно сделать, это привязать свойство, к которому вы хотите получить доступ в коде, к объекту.

Вы можете добавить TemplateField со скрытыми объектами и привязать значения, которые вы хотите использовать к ним, следующим образом:

<asp:TemplateField HeaderText="Remove">
<ItemTemplate>
    <asp:HiddenField ID="HiddenField1" runat="server" value='<%# Bind("FileName") %>'/>
 </ItemTemplate>

...