У меня проблема с управлением параллелизмом с Entity Framework.
Я определил класс Person
(Покажу только интересные детали)
public class Person
{
public Guid Id { get; set; }
public string Name { get; set; }
public Guid? CategoryId { get; set; }
public virtual Category Category { get; set; }
public byte[] TimeStamp { get; set; }
}
и класс для настройки
public class PersonConfiguration : EntityTypeConfiguration<Person>
{
public PersonConfiguration() : base()
{
HasKey(p => p.Id);
Property(p => p.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(p => p.TimeStamp)
.IsConcurrencyToken()
.HasColumnType("timestamp")
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed);
}
}
Точно так же я определил класс Category и соответствующий
класс для настройки
public class Category
{
public Guid Id { get; set; }
public string Title { get; set; }
public byte[] TimeStamp { get; set; }
}
public class CategoryConfiguration : EntityTypeConfiguration<Category>
{
public CategoryConfiguration() : base()
{
HasKey(c => c.Id);
Property(c => c.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(c => c.TimeStamp)
.IsConcurrencyToken()
.HasColumnType("timestamp")
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed);
}
}
В методе CommitChanges я ловлю исключение DbUpdateConcurrencyException
исключение и с помощью стратегии «выигрыши базы данных» я перезагружаю сущность из БД.
public int CommitChanges()
{
ret = -1;
try
{
ret = _context.SaveChanges();
}
catch (DbUpdateConcurrencyException e)
{
(e as DbUpdateConcurrencyException).Entries.Single().Reload();
throw new UowUpdateConcurrencyException();
}
catch (Exception e)
{
throw new Exception(e.Message);
}
return ret;
}
Для целей этого вопроса мы предполагаем, что за один раз в БД сохраняется только одна сущность
Нет проблем, если я сохраню категорию. Все тесты в порядке.
Проблема возникает, когда я пытаюсь сохранить человека (ранее загруженного через тот же контекст)
и есть нарушение параллелизма.
Я отлаживаю эту строку
(e as DbUpdateConcurrencyException).Entries.Single().Reload();
Сюрприз.
Исключение выдается правильно, но объект, который появляется из БД
имеет тип Категория вместо Персона.
Категория возврата.
(e as DbUpdateConcurrencyException).Entries.ToList()[0].Entity.GetType()
Если я отключу проверку параллелизма для категории, удалив свойство Timestamp в
в классе Category все отлично работает
Я думаю, что есть некоторая проблема со свойством навигации, которое я определил в классе Person.
Что вы думаете?
Спасибо!
UPDATE
Кажется, проблема в том, что я установил привязку между ComboBox и свойством Category.
Если я это прокомментирую, все работает нормально
<ComboBox ItemsSource="{Binding Path=CategoryList}"
DisplayMemberPath="Title"
SelectedValuePath="Id"
SelectedItem="{Binding Path=Category, Mode=TwoWay}" />
Если я связываю комбо с CategoryId, а не с Category, проблема все равно остается.
<ComboBox ItemsSource="{Binding Path=CategoryList}"
DisplayMemberPath="Title"
SelectedValuePath="Id"
SelectedValue="{Binding Path=CategoryId, Mode=TwoWay}" />