Hol*_*roe 7 entity-framework nullable optimistic-concurrency self-tracking-entities
我在更新Entity Framework实体中的外键时遇到问题.我正在使用自我跟踪实体并且具有一些具有某种关系的实体,其中外键也作为属性存在(EF4的新特征之一).密钥(整数)标记为Nullable并且修复了并发模式.
具体来说,我有一个与确认用户有很多到0..1关系的Alarm实体.(用户可以确认多个警报,但只能由零个或一个用户确认警报).
实体定义(简化):
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
Run Code Online (Sandbox Code Playgroud)
在我的自我跟踪实体中,确认用户ID按预期自动生成为Nullable,但是如果我将用户分配给已经持久的警报并运行ApplyChanges,则自我跟踪上下文扩展会尝试设置原始值(null) EF上下文(在上下文扩展中的SetValue中),但是以静默方式跳过,因为EdmType的ClrEquivalentType是一个不可为空的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);
}
Run Code Online (Sandbox Code Playgroud)
当EF稍后尝试更新我的警报时,我得到一个OptimisticConcurrencyException,因为它在UPDATE语句中构造一个WHERE子句,它使用0(零)作为原始用户外键值而不是正确的"is null".(WHERE子句是EF乐观并发机制的一部分,其中标记为"固定"并发模式的属性的原始值将再次检查数据库中的属性).
EF的自我跟踪实体是否完全支持可空的外键/原始类型?如果没有,我是否被迫使用虚拟实体而不是null或是否有其他解决方法?
更新 我试图在没有STE的情况下重现问题,但普通EF似乎很好地处理可以为空的外键的乐观并发,所以这是一个STE问题,而不是EF问题.自跟踪实体存在许多问题,因此这里存在故障并不奇怪.如果我找到可以在STE T4脚本中实现的解决方法,我将在此处发布.
| 归档时间: |
|
| 查看次数: |
5815 次 |
| 最近记录: |