Are nullable foreign keys allowed in Entity Framework 4?

蓝咒 提交于 2020-01-02 03:12:10

问题


I have a problem updating a foreign key in an Entity Framework entity. I am using self tracking entities and have an entity with some relations where the foreign key is also present as a property (one of the new features of EF4). The key (an integer) is marked as Nullable and Concurrency Mode fixed.

Specifically I have an Alarm entity with a many to 0..1 relationship to a confirming user. (a user may confirm several alarms, but an alarm can be confirmed by only zero or one users).

The entity definitions (simplified):

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

In my self tracking entity the confirming user id is auto-generated as a Nullable just as expected, however if I assign a user to an already persistent alarm and run ApplyChanges, the self tracking context extension tries to set the original value (null) in the EF context (In SetValue in the context extensions), but silently skips that because the ClrEquivalentType of the EdmType is a non-nullable Int32.

Auto-generated extension code:

    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);
    }

When the EF later tries to update my alarm I get an OptimisticConcurrencyException because it constructs a WHERE clause in the UPDATE statement where it uses 0 (zero) as the original user foreign key value instead of the correct "is null". (The WHERE clause is part of the EF optimistic concurrency mechanism, where the original values of the properties marked with "fixed" concurrency mode are checked agains the properties in the database).

Are nullable foreign keys / primitive types not fully supported in self tracking entities for EF? If not, am I forced to use dummy entities instead of null or are there other workarounds?

Update I have tried to reproduce the problem without STE, but plain EF seems to handle optimistic concurrency well for nullable foreign keys, so this is an STE problem, not an EF problem. There is numerous issues with self tracking entities, so it is not surprising that there is a glitch here. If I find a workaround that can be implemented in the STE T4 script I will post it here.


回答1:


Bill Huth posted a working patch at MSDN.




回答2:


Yes, nullable foreign keys are certainly allowed. We use them all over the place. You don't show your database or model, so it's difficult to be certain what the problem could be, but it sounds as though the Entity Framework cannot figure out the primary key of one of the tables involved. Perhaps you don't have one, maybe because one of them is a view? I'm guessing here, because you don't give much information about what you're doing.



来源:https://stackoverflow.com/questions/3598550/are-nullable-foreign-keys-allowed-in-entity-framework-4

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!