【问题标题】:Retrieving values of ReadOnly fields from DynamicData DetailsView in Edit Mode on Updating using LinqDataSource在使用 LinqDataSource 更新时,在编辑模式下从 DynamicData DetailsView 中检索 ReadOnly 字段的值
【发布时间】:2010-10-12 22:55:17
【问题描述】:

我的数据库中有几个表具有在插入和更新时设置的只读字段,即:AddDate (DateTime)、AddUserName (string)、LastModDate (DateTime)、LastModUserName (string)。

具有这些值的所有表都已设置为从以下接口继承:

public interface IUserTrackTable
{
    string AddUserName { get; set; }
    DateTime AddDate { get; set; }
    string LastModUserName { get; set; }
    DateTime LastModDate { get; set; }
}

因此,我在 Edit.aspx 页面上有以下方法:

protected void DetailsDataSource_Updating(object sender, LinqDataSourceUpdateEventArgs e)
{
    IUserTrackTable newObject = e.NewObject as IUserTrackTable;
    if (newObject != null)
    {
        newObject.LastModUserName = User.Identity.Name;
        newObject.LastModDate = DateTime.Now;
    }
}

但是,当它点击这个方法时,e.OriginalObject 已经丢失了所有四个字段的值,因此在实际更新期间会抛出 ChangeConflictException。我尝试将四个列名添加到 Init 事件处理程序中的 DetailsView1.DataKeyNames 数组:

protected void Page_Init(object sender, EventArgs e)
{
    // other things happen before this
    var readOnlyColumns = table.Columns.Where(c => c.Attributes.SingleOrDefaultOfType<ReadOnlyAttribute>(ReadOnlyAttribute.Default).IsReadOnly).Select(c => c.Name);
    DetailsView1.DataKeyNames = DetailsView1.DataKeyNames.Union<string>(readOnlyColumns).ToArray<string>();

    DetailsView1.RowsGenerator = new CustomFieldGenerator(table, PageTemplates.Edit, false);
    // other things happen after this
}

我已尝试使该代码仅在 PostBack 上发生,但仍然没有。我不知道如何获取所有列的值以进行往返。

CustomFieldGenerator 唯一处理 ReadOnlyAttribute 的事情,遵循C# Bits 上的详细信息。

更新:经过进一步调查,这些值会往返于 DetailsView_ItemUpdating 事件。所有值都存在于 e.OldValues 字典中。但是,当它到达 LinqDataSource_Updating 事件时,它们就会丢失。

显然,有一些“解决方案”可以让这些列不参与并发检查或其他涉及硬编码的方式,但理想的解决方案会在需要的地方动态添加适当的信息,以便保持动态解决方案。

【问题讨论】:

    标签: c#-4.0 dynamic-data detailsview asp.net-dynamic-data


    【解决方案1】:

    我 Drovani,我假设您想要数据审计(请参阅 Steve Sheldon 的 A Method to Handle Audit Fields in LINQ to SQL),我会在 EF4 的模型中执行此操作,您可以这样做:

    partial void OnContextCreated()
    {
        // Register the handler for the SavingChanges event. 
        this.SavingChanges += new EventHandler(context_SavingChanges);
    }
    
    private static void context_SavingChanges(object sender, EventArgs e)
    {
        // handle auditing
        AuditingHelperUtility.ProcessAuditFields(objects.GetObjectStateEntries(EntityState.Added));
        AuditingHelperUtility.ProcessAuditFields(objects.GetObjectStateEntries(EntityState.Modified), InsertMode: false);
    }
    
    internal static class AuditingHelperUtility
    {
        internal static void ProcessAuditFields(IEnumerable<Object> list, bool InsertMode = true)
        {
            foreach (var item in list)
            {
                IAuditable entity = item as IAuditable;
                if (entity != null)
                {
                    if (InsertMode)
                    {
                        entity.InsertedBy = GetUserId();
                        entity.InsertedOn = DateTime.Now;
                    }
    
                    entity.UpdatedBy = GetUserId();
                    entity.UpdatedOn = DateTime.Now;
                }
            }
        }
    }
    

    遗憾的是,EF v1 无法做到这一点

    【讨论】:

    • 看完你的回复后,我绝对有一个灵光乍现的时刻。我被困在我最初的盒子里,我什至没有想过将审计代码放在数据上下文中。这比我实施的解决方法还要好。感谢您帮助我解决了真正的问题,而不是我支持自己的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-13
    • 1970-01-01
    相关资源
    最近更新 更多