InvalidOperationException (collection is already set to an EntityCollection) after template modified that all properties are virtual

StackOverflow https://stackoverflow.com/questions/17829797

Domanda

Default tt for DbContext entities adds in entity's constuctor the initialization code for collection proeprties. Each collection is assigned empty HashSet

For scalar entity properties tt has this code:

public string Property(EdmProperty edmProperty)
{
    return string.Format(
        CultureInfo.InvariantCulture,
        "{0} {1} {2} {{ {3}get; {4}set; }}",
        Accessibility.ForProperty(edmProperty),
        _typeMapper.GetTypeName(edmProperty.TypeUsage),
        _code.Escape(edmProperty),
        _code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
        _code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
}

if I change it to:

public string Property(EdmProperty edmProperty)
{
    return string.Format(
        CultureInfo.InvariantCulture,
        "{0} {1} {2} {{ {3}get; {4}set; }}",
        AccessibilityAndVirtual(Accessibility.ForProperty(edmProperty)),
        _typeMapper.GetTypeName(edmProperty.TypeUsage),
        _code.Escape(edmProperty),
        _code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
        _code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
}

Adding AccessibilityAndVirtual() EF starts throwing InvalidOperationException saying that collection is already set to an EntityCollection.

Why do this happen?

UPDATE:

Removing virtual from the PK property removed the exception.

È stato utile?

Soluzione

Exception is thrown only if PK property is virtual, so I changed code of Property a little

public string Property(EdmProperty edmProperty, MetadataTools ef)
{
    var acessability = Accessibility.ForProperty(edmProperty);

    return string.Format(
        CultureInfo.InvariantCulture,
        "{0} {1} {2} {{ {3}get; {4}set; }}",
        ef.IsKey(edmProperty) ? acessability : AccessibilityAndVirtual(acessability),
        _typeMapper.GetTypeName(edmProperty.TypeUsage),
        _code.Escape(edmProperty),
        _code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
        _code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
}

Altri suggerimenti

I know this is an old question, but I had the same problem and the answer of @Pavel didn't work for me.

It turned out that When you make all properties virtual, you're implementing Change Tracking Proxies. In this case, The change tracking proxy will override any collection navigation properties and use its own collection type (EntityCollection). That's why you have to cancel any initialization of the navigation properties in the constructors of the classes. ( delete NavigationProperty = new HashSet() in every partial class )

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top