引发实体数据源删除事件时实体中的空值

发布于 2024-12-06 18:16:09 字数 969 浏览 3 评论 0原文

我目前正在使用实体框架,并且有一个 Gridview 显示数据库中的记录列表。我有一个“删除”按钮,它使用“删除”命令。每条记录在服务器上都有一个与其关联的文件,因此当数据源引发删除事件时,我想获取文件名并从服务器中删除该文件。奇怪的是,在我的 ds_Deleting 事件中,实体中的某些值为空。我似乎不明白为什么。

gridview 中的“删除”按钮的代码如下:

<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 中正确显示。任何帮助将不胜感激。谢谢!

I'm currently using the Entity Framework and I have a Gridview displaying a list of records from a database. I have a Remove button the uses the Delete command. Each record has a file on the server associated with it, so when the data source raises the deleting event I want to grab the filename and delete the file from the server as well. The weird thing is that in my ds_Deleting event some of the values in the entity are null. I can't seem to figure out why.

The code for my Delete button in the gridview is the following:

<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>

The OnDeleting event in the codebehind looks like this:

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

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

Every time the contract.FileName value is null, even though it is displayed properly in the GridView. Any help would be much appreciated. Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

呆° 2024-12-13 18:16:09

我设法弄清楚了这一点,并决定将其写在这里,以防其他人遇到同样的问题。我检查了MSDN上的文档以了解实体数据源的删除事件(可以找到这里)它说

EntityDataSourceChangingEventArgs 对象的 Entity 属性用于访问要删除的对象。该对象的属性可能未完全设置。只需设置识别对象所需的属性。

这就是为什么我得到空值的原因。我想出的解决方案可能并不理想,但它有效。我意识到主键 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));
    }
}

I managed to figure this out and decided I'd write it down here in case anyone else has the same problem. I checked the documentation on MSDN for the deleting event of the entity data source (which can be found here) and it said

The Entity property of the EntityDataSourceChangingEventArgs object is used to access the object to be deleted. The properties of this object may not be fully set. Only the properties required to identify the object must be set.

So this is why I was getting null values. The solution I came up with probably isn't ideal but it works. I realized the primary key ContractID always had a value so I used it to pull the record from the database. Here is my code:

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));
    }
}
往日情怀 2024-12-13 18:16:09

在 ASP.NET 动态数据列表页面中经历过这种情况,并且考虑到 varchar 外键似乎存在错误(我相信 Microsoft 已接受),任何解决方案都将是一种解决方法(hack)。

为了解决具有默认值(例如createdDate、CreatedBy 等)的表列的空值,我最终在相关实体的分部类的构造函数中设置默认值。

上面的信息提供了仅加载唯一标识实体所需的列的线索后,我发现为问题(外键)列添加另一个“默认”值解决了我的问题 - 即因为我没有任何级联删除或其他任何内容,实体的主键足以执行删除,并且其他处理正在检查外键(varchar)中的空值 - 所以我只需在构造函数中将该列设置为 String.Empty ,并且默认值我设置被忽略...

例如

public partial class MyEntity
{

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

等瞧!

Having experienced this with an ASP.NET Dynamic Data List page, and given that there appears to be a bug with varchar foreign keys (accepted by Microsoft I believe), any solution would be something of a workaround (hack).

In order to work around null values for table columns with default values (e.g. createdDate, CreatedBy etc), I've ended up with setting default values in the constructor of a partial class for the entity concerned.

After the information above gave the clue that only the columns required to uniquely identify the entity are loaded, I found that adding another 'default' value for the problem (foreign key) column fixed my issue - i.e. because I don't have any cascade delete or anything else, the primary key of the entity is enough to do the delete, and it's other processing that's checking for null values in the foreign key (varchar) - so I simply set that column to String.Empty in the contructor, and the default value I set is ignored...

e.g.

public partial class MyEntity
{

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

et voila!

漆黑的白昼 2024-12-13 18:16:09

您所要做的就是将您想要在后面的代码中访问的属性绑定到一个对象。

您可以添加带有隐藏对象的 TemplateField 并将要使用的值绑定到它们,如下所示:

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

All you have to do is to Bind the property you want to access in the code behind to an object.

You could add a TemplateField with Hidden objects and Bind the values you want to use to them like this :

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文