Entity Framework中对应于Entity的代理类

在使用Entity Framework的时候,发现_userService.GetUserById(int id)返回的对象并不是User, 而是类似于System.Data.Entity.DynamicProxies.Blog_5E43C6C196972BF0754973E48的一个代理类。其实,在很多ORM框架,如NHibernate中,都有这样一种机制,目的是方便延迟加载。所有能使用User的地方,都可以使用User的代理类,因为这个代理类是从User继承而来的。以下内容摘自MSDN,讲了如何禁用代理,如何显式的创建一个代理类等。


When creating instances of POCO entity types, the Entity Framework often creates instances of a dynamically generated derived type that acts as a proxy for the entity. This proxy overrides some virtual properties of the entity to insert hooks for performing actions automatically when the property is accessed. For example, this mechanism is used to support lazy loading of relationships. The techniques shown in this topic apply equally to models created with Code First and the EF Designer.

 

Disabling proxy creation

Sometimes it is useful to prevent the Entity Framework from creating proxy instances. For example, serializing non-proxy instances is considerably easier than serializing proxy instances. Proxy creation can be turned off by clearing the ProxyCreationEnabled flag. One place you could do this is in the constructor of your context. For example:


  
  
  1. public class BloggingContext : DbContext
  2. {
  3.     public BloggingContext()
  4.     {
  5.         this.Configuration.ProxyCreationEnabled = false;
  6.     } 
  7.  
  8.     public DbSet<Blog> Blogs { get; set; }
  9.     public DbSet<Post> Posts { get; set; }
  10. }

Note that the EF will not create proxies for types where there is nothing for the proxy to do. This means that you can also avoid proxies by having types that are sealed and/or have no virtual properties.

 

Explicitly creating an instance of a proxy

A proxy instance will not be created if you create an instance of an entity using the new operator. This may not be a problem, but if you need to create a proxy instance (for example, so that lazy loading or proxy change tracking will work) then you can do so using the Create method of DbSet. For example:


  
  
  1. using (var context = new BloggingContext())
  2. {
  3.     var blog = context.Blogs.Create();
  4. }

The generic version of Create can be used if you want to create an instance of a derived entity type. For example:


  
  
  1. using (var context = new BloggingContext())
  2. {
  3.     var admin = context.Users.Create<Administrator>();
  4. }

Note that the Create method does not add or attach the created entity to the context.

Note that the Create method will just create an instance of the entity type itself if creating a proxy type for the entity would have no value because it would not do anything. For example, if the entity type is sealed and/or has no virtual properties then Create will just create an instance of the entity type.

 

Getting the actual entity type from a proxy type

Proxy types have names that look something like this:

System.Data.Entity.DynamicProxies
.Blog_5E43C6C196972BF0754973E48C9C941092D86818CD94005E9A759B70BF6E48E6

You can find the entity type for this proxy type using the GetObjectType method from ObjectContext. For example:


  
  
  1. using (var context = new BloggingContext())
  2. {
  3.     var blog = context.Blogs.Find(1);
  4.     var entityType = ObjectContext.GetObjectType(blog.GetType());
  5. }

Note that if the type passed to GetObjectType is an instance of an entity type that is not a proxy type then the type of entity is still returned. This means you can always use this method to get the actual entity type without any other checking to see if the type is a proxy type or not.


对于ORM的延迟加载的简单原理,可以参考博客 NHIBERNATE延迟加载的原理与代理模式,简单的说,就是在实体的代理类中设置了一些额外的与每个属性对应的,用于标记每个属性状态的bool属性,当调用实体属性属性的get方法的时候,先查看状态是否是loaded,如果没有的话,此时再调用与数据库的连接来load记录。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值