В моей базе данных есть несколько таблиц, которые имеют поля только для чтения, которые устанавливаются при вставке и обновлении, а именно: AddDate (DateTime), AddUserName (строка), LastModDate (DateTime), LastModUserName (строка).
Все таблицы, имеющие эти значения, были унаследованы от следующего интерфейса:
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 выдается во время фактического обновления. Я попытался добавить имена четырех столбцов в массив DetailsView1.DataKeyNames в обработчике события Init:
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 обрабатывает атрибут ReadOnly, следуя указаниям C # битов .
ОБНОВЛЕНИЕ: После дальнейшего исследования значения совершают обратное путешествие к событию DetailsView_ItemUpdating. Все значения присутствуют в словаре e.OldValues. Однако они теряются к тому времени, когда оно попадает в событие LinqDataSource_Updating.
Очевидно, что есть «решения», позволяющие не использовать эти столбцы в параллельных проверках или других способах, связанных с жестким кодированием, но идеальное решение будет динамически добавлять соответствующую информацию, где это необходимо, чтобы это оставалось динамическим решением.