具体来说,我有一个报警实体,与确认用户有多到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
自动生成的扩展代码:
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,因为它在update语句中构造了一个WHERE子句,其中它使用0(零)作为原始用户外键值,而不是正确的“is null”。(WHERE子句是EF乐观并发机制的一部分,在该机制中,用“fixed”并发模式标记的属性的原始值将在数据库中的属性中重新检查)。
EF的自跟踪实体是否不完全支持可空外键/基元类型?
如果不是,我是被迫使用虚拟实体而不是null还是有其他的解决方法?
我曾尝试在没有STE的情况下重现这个问题,但是对于可为空的外键,普通EF似乎可以很好地处理乐观并发,因此这是STE问题,而不是EF问题。