2

我对 EF 5 和循环引用的延迟加载有疑问。

下图代表我的模型。 在此处输入图像描述

主要问题在于 Model 和 ModelProperties 类之间,因为 Model 包含 IEnumerable 导航属性,而 ModelProperty 包含 Model 导航属性。

所以这个设计导致下面的情况 在此处输入图像描述

您可以访问全尺寸图片http://tinypic.com/r/2vskuxl/6

正如您可以想象的那样,这会导致非常大的问题,OutOfMemory 异常。

我能找到的唯一解决方案是禁用延迟加载并使用其他方法。但是延迟加载非常简化我们的工作。我希望有一个配置或一个属性来帮助我加载只有两个级别的关系和延迟加载。

有什么办法可以做到这一点?

更新: 关于 Julie Lerman 的请求,这里是 EF 的视觉模型。我强调了导致问题的主要关系。 您也可以在http://tinypic.com/r/30v15pg/6在此处输入图像描述 访问全尺寸

更新 2: 这是模型定义。

public class Model {
        public int ModelID { get; set; }
        public int BrandID {
            get;
            set;
        }
        public virtual Brand Brand { get; set; }
        public string Logo { get; set; }
        public string Name { get; set; }
        public virtual ICollection<ModelProperty> ModelProperties {
            get;
            set;
        }
}

public class ModelProperty {

    public int ModelPropertyID {
        get;
        set;
    }

    public virtual int PropertyDefinitionID {
        get;
        set;
    }

    public virtual PropertyDefinition PropertyDefinition {
        get;
        set;
    }

    public virtual int ModelID {
        get;
        set;
    }

    public virtual Model Model {
        get;
        set;
    }

    public bool IsContainable {
        get;
        set;
    }

    public bool HasFilterDefinition {
        get;
        set;
    }

    public virtual ICollection<ModelPropertyValue> ModelPropertyValues {
        get;
        set;
    }

    public virtual ICollection<ModelPropertyMatchingFilter> ModelPropertyMatchingFilter {
        get;
        set;
    }
}

ModelProperty 还有一个实体配置。

 public class ModelPropertyEntityTypeConfiguration : EntityTypeConfiguration<ModelProperty> {
        public ModelPropertyEntityTypeConfiguration() {
            HasKey(p => p.ModelPropertyID);

            HasRequired(p => p.PropertyDefinition).WithMany(s => s.ModelProperties).HasForeignKey(s => s.PropertyDefinitionID).WillCascadeOnDelete(false);
            HasRequired(p => p.Model).WithMany(s => s.ModelProperties).HasForeignKey(s => s.ModelID).WillCascadeOnDelete(false);
            HasMany(p => p.ModelPropertyValues).WithRequired(s => s.ModelProperty).HasForeignKey(s => s.ModelPropertyID).WillCascadeOnDelete(true); 
            HasMany(p => p.ModelPropertyMatchingFilter).WithRequired(s => s.ContainerModelProperty).HasForeignKey(s => s.ContainerModelPropertyID).WillCascadeOnDelete(false);
            ToTable("dbo.ModelProperties");
        }
    }

更新 3: 我不确定,但 Automapper 也会导致这种情况。因为 Entity Framework Profile 告诉成千上万的 Autommaper 方法在运行时被调用。

更新 4: 这是 EFProf 堆栈跟踪: 在此处输入图像描述 您可以访问更大的版本http://tinypic.com/r/21cazv4/6

更新 5 您可以在此处查看示例项目:https ://github.com/bahadirarslan/AutomapperCircularReference 在示例中,您可以通过快速观看轻松查看无限循环。

4

2 回答 2

1

感谢更新。你的模特看起来不错。它肯定知道这只是一个 1:* 关系。拉迪斯拉夫(像往常一样)是正确的。LL 不会导致问题...除了在序列化期间的一个地方。您是否有机会在服务中使用您的代码?使用常规延迟加载,只有您明确提及的属性才会延迟加载。但是在序列化过程中,序列化“提及”了每个属性,因此它只是在整个图形中不断加载和加载属性,并导致循环依赖问题。对于服务,我们必须在返回数据之前关闭延迟加载(使用 context.configuration.lazyloadingenabled=false)。因此,在 service 方法中,您可以预先加载、延迟加载或显式加载来获取图表,然后在返回结果之前禁用延迟加载。

于 2013-03-17T13:28:54.277 回答
1

您应该禁用延迟加载以绕过代理对象,或者您应该将所需的内容作为 DTO 返回。首选使用 DTO,因为它隐藏了您的域的详细信息

于 2013-03-18T13:15:03.280 回答