首页 新闻 会员 周边 捐助

Entity framework 5 code first 新添加的实体对象无法启用延迟加载?

0
悬赏园豆:10 [已解决问题] 解决于 2013-09-11 10:40

这是类似问题的链接:

我想知道具体原因是什么,上面链接给的答案看得个大概,不是很明白。

为什么新添加的元素,然后进行查询,结果就无法只使用延迟加载呢,无法生成动态代理对象呢?而查询已经存在的元素则可以使用延迟加载,并且能够正确生成动态代码对象?

麻烦熟悉的园友再给解释解释^_^

 

问题代码截图:

 

    public class OrgChart
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int Id { get; set; }
        public string Name { get; set; }
        public virtual IList<OrgNode> Nodes { get; set; }
    }


    public class OrgNode
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int Id { get; set; }
        public string Name { get; set; }
        public virtual OrgChart Chart { get; set; }
        public virtual IList<User> Users { get; set; }
    }

    public class User
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int Id { get; set; }
        public string Name { get; set; }
        public virtual OrgNode Node { get; set; }
    }
kaleyroy的主页 kaleyroy | 菜鸟二级 | 园豆:360
提问于:2013-09-10 19:45
< >
分享
最佳答案
0

你需要把 OrgNode 实例的创建委托给 DbContext 来执行,这样它才能在 OrgNode 构造时注入额外的代理逻辑,从而实现 延迟加载(可以同 IoC 、AOP概念做个比较,也可以使用下 Unity。这么看来,EF 采用了构造注入,而没实现属性注入 )。

收获园豆:5
Launcher | 高人七级 |园豆:45050 | 2013-09-11 09:43

Hi Launcher,

那这样的话我们平时的用法:
        /// <summary>
        /// Add entity
        /// </summary>
        /// <param name="entity">New entity</param>
        public virtual void Add(T entity)
        {
            this.Context.Set<T>().Add(entity);
            this.Context.SaveChanges();
        }

这样不是有问题?按照你的解释,我们是不是应该这样:

OrgNode node = db.Set<OrgNode>().Create();
node.xx = xxx.

//然后再调用Add方法 Add(node);
kaleyroy | 园豆:360 (菜鸟二级) | 2013-09-11 10:02

@kaleyroy: 对,通过 EF 来创建实体。

Launcher | 园豆:45050 (高人七级) | 2013-09-11 10:05

@Launcher: 

按照你的步骤,也是OK的。

不过我有些疑问,比如我用Repository模式,不想暴露DbContext在外部使用。

我只能再在内部拼装我的实体? 还有其他的方式吗?

kaleyroy | 园豆:360 (菜鸟二级) | 2013-09-11 10:24

@kaleyroy: Repository 应该提供 Create 方法,我记得 DDD 中仓储模式是建议给对象的创建提供工厂方法的。 也就是说你的代码中不应该存在 new 对象的语句,而统一使用 Repository 的 Create 方法在仓储中创建一个新的对象,这也比较符合 DDD 的语义。

Launcher | 园豆:45050 (高人七级) | 2013-09-11 10:25

@Launcher: 

明白,谢谢^_^

kaleyroy | 园豆:360 (菜鸟二级) | 2013-09-11 10:40
其他回答(1)
0

新添加的属性增加virtual了吗?

收获园豆:5
dudu | 园豆:30948 (高人七级) | 2013-09-10 20:57

哈哈。。。 谢谢dudu.

是加了,这个我忘贴上去了,我补充下剩下的内容。

支持(0) 反对(0) kaleyroy | 园豆:360 (菜鸟二级) | 2013-09-10 22:46

@kaleyroy: 还是没看明白,究竟是哪个新添加的元素无法延迟加载?

支持(0) 反对(0) dudu | 园豆:30948 (高人七级) | 2013-09-11 09:50

@dudu: 

你看到这张截图里面 newNode的类型是 OrgNode,这个OrgNode里面的属性比如Users是不具有延迟加载功能的。

而这张截图里面的existsNode类型是DynamicProxies.OrgNode_34.... 动态代理类型,这种类型才具有延迟加载功能。

支持(0) 反对(0) kaleyroy | 园豆:360 (菜鸟二级) | 2013-09-11 09:54

@kaleyroy: 

试试将newNode的代码放到单独的ExampleDbContext中查询

支持(0) 反对(0) dudu | 园豆:30948 (高人七级) | 2013-09-11 09:58

@dudu: 

嗯,这样是可以的。不过好像我们的场景一般都局部共享一个DbContext.

支持(0) 反对(0) kaleyroy | 园豆:360 (菜鸟二级) | 2013-09-11 10:22

@kaleyroy: 对于这样的场景,EF认为没有必要生成代理类,我也这么认为

支持(0) 反对(0) dudu | 园豆:30948 (高人七级) | 2013-09-11 10:31

@dudu: 

明白,谢谢dudu!

支持(0) 反对(0) kaleyroy | 园豆:360 (菜鸟二级) | 2013-09-11 10:40
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册