我的数据库中有几个表具有在插入和更新时设置的只读字段,即: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 上发生,但仍然没有。我不知道如何获取所有列的值以进行往返。
根据C# Bits的详细信息,CustomFieldGenerator 唯一处理的是 ReadOnlyAttribute 。
更新:经过进一步调查,这些值会往返于 DetailsView_ItemUpdating 事件。所有值都存在于 e.OldValues 字典中。但是,当它到达 LinqDataSource_Updating 事件时,它们会丢失。
显然,存在使这些列不参与并发检查或其他涉及硬编码的方式的“解决方案”,但理想的解决方案将在需要的地方动态添加适当的信息,以便保持动态解决方案。