我有一个用于搜索的通用基存储库方法(为清晰起见而进行了修剪):
public class Repository<TRepository> : IRepository<TRepository>
where TRepository : class, IEntity, new()
{
public virtual IQueryable<TRepository> SearchFor(Expression<Func<TRepository, bool>> predicate, Expression<Func<TRepository, bool>> orderbylinq = null)
{
if (orderbylinq == null)
{
return DbSet.Where(predicate);
}
else
{
return DbSet.Where(predicate).OrderBy(orderbylinq);
}
}
}
我有一个派生的存储库类:
public class TimeDetailRepository : Repository<TimeDetail>
在我的服务层中,有一个调用SearchFor方法的类:
private TimeDetailRepository _timeDetailRepository;
public ManageTimeDetailsAppServ()
: base(new TimeDetailRepository())
{
_timeDetailRepository = new TimeDetailRepository();
}
IQueryable<TimeDetail> timeDetails2 = _timeDetailRepository.SearchFor(
x => x.Id == 3214);
在本例中,timeDetails2是完全加载的(所有相关实体都已加载)。
但是,我有另一个类(基本服务层类)进行相同的SearchFor调用,但它没有加载相关实体:
IQueryable<TRepository> dbEntity = _repository.SearchFor(x => x.Id == result.Value);
在这两个调用中,我都试图创建一个视图模型,该模型利用来自相关实体的属性值。为什么要在一种情况下而不是另一种情况下装载它们?这是相同的实体TimeDetail,相同的基础存储库类?
在调试器中看到的图像。为什么某些相关实体会被加载(比如设施,和TimeDetailStatus),而其他实体则不会被加载(比如OrderHeader或客户)
更新
我查看了正在生成的查询,它们看起来都很相似,即它们没有连接到另一个tables...so --上下文是否可能已经包含了来自一些相关实体的一些缓存行,这就是它们是如何被包含的?
发布于 2013-04-17 14:10:27
除非在集合上使用.Include()
方法,否则EF将执行延迟加载。因为你没有那样做,所以你不会立即得到它们,但是当你召唤它们时,你会懒洋洋地把它们装上。
但是,只有在对象上下文仍然打开的情况下,这才有效。如果上下文没有了,那么连接到数据库的能力就消失了,所以属性都是空的。
我的猜测是,你所看到的差异与你如何保持周围的环境有关。这很难说,因为你没有显示你的背景,但我会从那里开始。
编辑
不确定这是否与你的问题有任何关系,但我只是想澄清懒惰加载的东西。下面是我最喜欢的EF示例:两个表:作者(AuthorId,AuthorName)和图书(BookId,AuthorId(FK),BookTitle)
/* 1 */ static void Main(string[] args)
/* 2 */ {
/* 3 */ Book book;
/* 4 */ using (var context = new SampleDbEntities())
/* 5 */ {
/* 6 */ book = context.Books.Single(b => b.BookId == 1);
/* 7 */ }
/* 8 */
/* 9 */ try
/* 10 */ {
/* 11 */ Console.WriteLine(book.Author.AuthorName);
/* 12 */ }
/* 13 */ catch (Exception ex)
/* 14 */ {
/* 15 */ Console.WriteLine(ex.Message);
/* 16 */ }
/* 17 */
/* 18 */ Console.ReadLine();
/* 19 */ }
如果您按-原样运行此代码,则会发生以下情况:
Books
表,并使用匹配的记录填充book
变量。数据库中从未触及过Authors
表。Author
属性的异常。但是,如果您使用调试器并在第7行停止,只需在一瞬间查看图书变量,它将立即查询数据库中的Authors
表(在调试器中),并在该对象上填充Author
属性。这就是我所说的延迟加载的意思--当您实际访问该属性时,即使在调试器中,当上下文处于活动状态时,它也会发出一个新的数据库调用。现在您可以继续代码了,第11行就可以了,作者的名字将被打印出来。
因此,基本上,当涉及到EF时,不要信任调试器。它懒散地加载数据,尽管它看起来不像这样。要想搞清楚到底发生了什么,最好的办法就是启动,并查看哪些查询正在运行。
https://stackoverflow.com/questions/16070148
复制