Search code examples
c#entity-frameworkentity-framework-4dbcontextobjectcontext

Different setter behavior between DbContext and ObjectContext


(This is using EntityFramework 4.2 CTP)

I haven't found any references to this on the web yet, although it's likely I'm using the wrong terminology while searching. There's also a very likely scenario where this is 100% expected behavior, just looking for confirmation and would rather not dig through the tt template (still new to this).

Assuming I have a class with a boolean field called Active and I have one row that already has this value set to true. I have code that executes to set said field to True regardless of it's existing value.

  • If I use DbContext to update the value to True no update is made.
  • If I use ObjectContext to update the value an update is made regardless of the existing value.

This is happening in the exact same EDMX, all I did was change the code generation template from DbContext to EntityObject.

Update:

Ok, found the confirmation I was looking for...consider this a dupe...next time I'll do MOAR SEARCHING!

Entity Framework: Cancel a property change if no change in value

Update 2:

Answer (or at least the solution I found) moved to actual answer as requested...


Solution

  • As requested, the answer to my own question (sorry)...

    Problem: the default tt template wraps the "if (this != value)" in the setter with "if (iskey), so only primarykey fields receive this logic.

    Solution: it's not the most graceful thing, but I removed this check...we'll see how it pans out in real usage. I included the entire tt template, my changes are denoted with **...

    Update: confirmed and worked around using same method in Entity-Framework 5 Beta 2

    ////////
    ////////  Write SimpleType Properties.
    ////////
    private void WriteSimpleTypeProperty(EdmProperty simpleProperty, CodeGenerationTools code)
    {
        MetadataTools ef = new MetadataTools(this);
    #>
    
    /// <summary>
    /// <#=SummaryComment(simpleProperty)#>
    /// </summary><#=LongDescriptionCommentElement(simpleProperty, 1)#>
    [EdmScalarPropertyAttribute(EntityKeyProperty=       <#=code.CreateLiteral(ef.IsKey(simpleProperty))#>, IsNullable=<#=code.CreateLiteral(ef.IsNullable(simpleProperty))#>)]
    [DataMemberAttribute()]
    <#=code.SpaceAfter(NewModifier(simpleProperty))#><#=Accessibility.ForProperty(simpleProperty)#> <#=MultiSchemaEscape(simpleProperty.TypeUsage, code)#> <#=code.Escape(simpleProperty)#>
    {
        <#=code.SpaceAfter(Accessibility.ForGetter(simpleProperty))#>get
        {
    <#+             if (ef.ClrType(simpleProperty.TypeUsage) == typeof(byte[]))
                {
    #>
            return StructuralObject.GetValidValue(<#=code.FieldName(simpleProperty)#>);
    <#+
                }
                else
                {
    #>
            return <#=code.FieldName(simpleProperty)#>;
    <#+
                }
    #>
        }
        <#=code.SpaceAfter(Accessibility.ForSetter((simpleProperty)))#>set
        {
    <#+
            **//if (ef.IsKey(simpleProperty)) 
            **//{
                if (ef.ClrType(simpleProperty.TypeUsage) == typeof(byte[]))
                {
    #>
            if (!StructuralObject.BinaryEquals(<#=code.FieldName(simpleProperty)#>, value))
    <#+
                }
                else
                {
     #>
            if (<#=code.FieldName(simpleProperty)#> != value)
    <#+
                }
    #>
            {
    <#+
        PushIndent(CodeRegion.GetIndent(1));
            **//}
    #>
            <#=ChangingMethodName(simpleProperty)#>(value);
            ReportPropertyChanging("<#=simpleProperty.Name#>");
            <#=code.FieldName(simpleProperty)#> = <#=CastToEnumType(simpleProperty.TypeUsage, code)#>StructuralObject.SetValidValue(<#=CastToUnderlyingType(simpleProperty.TypeUsage, code)#>value<#=OptionalNullableParameterForSetValidValue(simpleProperty, code)#>, "<#=simpleProperty.Name#>");
            ReportPropertyChanged("<#=simpleProperty.Name#>");
            <#=ChangedMethodName(simpleProperty)#>();
    <#+
        **//if (ef.IsKey(simpleProperty))
            **//{
        PopIndent();
    #>
            }
    <#+
            **//}
    #>
        }
    }