У меня проблема с обновлением внешнего ключа в сущности Entity Framework.Я использую сущности самопроверки и имею сущность с некоторыми отношениями, где внешний ключ также присутствует в качестве свойства (одна из новых функций EF4).Ключ (целое число) помечается как Nullable и фиксированный режим параллелизма.
В частности, у меня есть объект Alarm с отношением «много к 0..1» для подтверждающего пользователя.(пользователь может подтвердить несколько сигналов тревоги, но сигнал тревоги может подтвердить только ноль или один пользователь).
Определения объекта (упрощенно):
Alarm properties
Id Int32 non-nullable identity entity key
UserId Int32 nullable concurrency mode fixed
Alarm navigation properties
User 0..1 multiplicity
User properties
Id Int32 non-nullable identity entity key
Name String non-nullable
В моем объекте самоконтроляПодтверждение того, что идентификатор пользователя автоматически генерируется как Nullable, как и ожидалось, однако, если я назначаю пользователя для уже сохраняющегося сигнала тревоги и запускаю ApplyChanges, расширение контекста самотрекинга пытается установить исходное значение (null) в контексте EF (в SetValueв контекстных расширениях), но молча пропускает это, поскольку тип ClrEquivalentType для EdmType является ненулевым Int32.
Сгенерированный автоматически код расширения:
private static void SetValue(this OriginalValueRecord record, EdmProperty edmProperty, object value)
{
if (value == null)
{
Type entityClrType = ((PrimitiveType)edmProperty.TypeUsage.EdmType).ClrEquivalentType;
if (entityClrType.IsValueType &&
!(entityClrType.IsGenericType && typeof(Nullable<>) == entityClrType.GetGenericTypeDefinition()))
{
// Skip setting null original values on non-nullable CLR types because the ObjectStateEntry won't allow this
return;
}
}
int ordinal = record.GetOrdinal(edmProperty.Name);
record.SetValue(ordinal, value);
}
Когда EF позже пытаетсяобновить мою тревогу, я получаю OptimisticConcurrencyException, потому что он создает предложение WHERE в инструкции UPDATE, где он использует 0 (ноль) в качестве исходного значения внешнего ключа пользователя вместо правильного "является нулевым".(Предложение WHERE является частью механизма оптимистического параллелизма EF, в котором исходные значения свойств, помеченных с помощью «фиксированного» режима параллелизма, проверяются снова и снова в свойствах базы данных).
Являются обнуляемыми внешними ключами / примитивными типамине полностью поддерживается в объектах самоконтроля для EF?Если нет, я вынужден использовать фиктивные сущности вместо нуля или есть другие обходные пути?
Обновление Я пытался воспроизвести проблему без STE, но простой EF, кажется, обрабатывает оптимистичный параллелизмхорошо для внешних ключей, которые можно обнулять, так что это проблема STE, а не проблема EF.Существует множество проблем с самообследованием сущностей, поэтому неудивительно, что здесь есть сбой.Если я найду обходной путь, который может быть реализован в сценарии STE T4, я опубликую его здесь.