Получение значений полей ReadOnly из подробного представления DynamicData в режиме редактирования при обновлении с использованием LinqDataSource - PullRequest
0 голосов
/ 13 октября 2010

В моей базе данных есть несколько таблиц, которые имеют поля только для чтения, которые устанавливаются при вставке и обновлении, а именно: 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.

Очевидно, что есть «решения», позволяющие не использовать эти столбцы в параллельных проверках или других способах, связанных с жестким кодированием, но идеальное решение будет динамически добавлять соответствующую информацию, где это необходимо, чтобы это оставалось динамическим решением.

1 Ответ

0 голосов
/ 12 декабря 2010

i Drovani, я предполагаю, что вы хотите провести аудит данных (см. Метод обработки полей аудита в 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

...