在模板修改后,所有属性都是虚拟的,InvalidOperationException(集合已设置为EntityCollection)

时间:2013-07-24 09:14:54

标签: entity-framework entity-framework-4.1 entity-framework-5 t4 dbcontext

DbContext实体的默认tt在实体的构造函数中添加了集合proeprties的初始化代码。每个集合都分配了空的HashSet

对于标量实体属性,tt具有以下代码:

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

如果我将其更改为:

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

添加AccessibilityAndVirtual()EF开始抛出InvalidOperationException,说集合已经设置为EntityCollection。

为什么会这样?

更新

从PK属性中删除虚拟删除了异常。

2 个答案:

答案 0 :(得分:3)

仅当PK属性为虚拟时才抛出异常,因此我稍微更改了Property的代码

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

答案 1 :(得分:0)

我知道这是一个老问题,但是我遇到了同样的问题,@ Pavel的答案对我不起作用。

原来,当您将所有属性虚拟化时,您正在实现变更跟踪代理。在这种情况下,更改跟踪代理将覆盖所有集合导航属性,并使用其自己的集合类型(EntityCollection)。这就是为什么您必须在类的构造函数中取消导航属性的任何初始化。 (在每个局部类中删除NavigationProperty = new HashSet())