当其关于映射或不映射,我会选择A.有许多优点导航属性(如Customer.Supplier
),并有很多方法来控制懒惰/渴望加载。
导航属性的优点是linq查询更容易编写。未落你必须写一个连接:
随着加入:
from supp in db.Supliers
join serv in db.Services on supp.SupplierId equals serv.SupplierId
select ...
随着导航属性
from supp in db.Supliers
from serv in supp.Services
select ...
或者这样的事情:
from supp in db.Supliers
select new { supp.Name, ServicesCount = supp.Services.Count() }
和EF会弄清楚如何在SQL中进行连接。
具有导航属性并不意味着它们总是被加载。对于延迟加载的情况发生,两个条件必须满足
- 的属性必须被定义为
virtual
使EF与接线来覆盖它在一个代理类型卡里了延迟加载。
- 上下文必须启用延迟加载。它们是默认设置,但您可以通过设置
context.Configuration.LazyLoadingEnabled = false
将其关闭。
因此,这也显示了两种控制延迟加载的方法:您可以在结构上或临时启用/禁用它。
除此之外,你可以控制的对面,预先加载,有两种方式:
使用Include
声明:
db.Suppliers.Include(s => s.Services)
包括预测的导航性能:
from supp in db.Supliers
from serv in supp.Services
select new { supp.Name, serv.ServiceName }
(有更多的方法,但这些是最重要的)
这将适用于在您的服务或存储库中编写linq查询。正如其他人所说:不要将IQueryable
暴露给您的服务/存储库方法的消费者。
最后一个重要提示:延迟加载只能在生活环境的范围内进行。如果上下文处置并且加载了延迟加载的导航属性,则会引发异常。同时建议使用寿命短的上下文实例。所以存在这样的两难:暴露实体对象或者只暴露DTO或查看模型或类似的东西。当您公开延迟加载启用的实体对象时,消费者可能无意中寻址尚未加载的导航属性,并且上下文消失。
使用Linq和存储过程来得到你需要的东西 – CR41G14 2013-02-13 15:03:03
哪种架构?我的意思是,一旦从数据库中检索到实体就被序列化了吗? – ken2k 2013-02-13 15:04:53
@ CR41G14我想避免存储过程,有许多具有相同表格布局的数据库。因此,从软件调用更适合于我的域 – tom 2013-02-13 15:04:57