我有一个具有三个独立子实体的实体,所有这些实体都需要一次性加载到数据库中(我想象的是典型的急切加载场景)。
当我拨打以下电话时:
public IQueryable<Participant> GetAllWithAllIncluded()
{
dbSet.Include(p => p.EmailNotices).Load();
dbSet.Include(p => p.EmailTemplatePlaceholders).Load();
dbSet.Include(p => p.Actions).Load();
return dbSet;
}
它在SQL配置文件中生成以下条目:
SQL:BatchStarting SELECT ...
SQL:BatchCompleted SELECT ...
SQL:BatchStarting SELECT ...
SQL:BatchCompleted SELECT ...
SQL:BatchStarting SELECT ...
SQL:BatchCompleted SELECT ...
RPC:Completed exec sp_executesql N'SELECT ...
这是否意味着在某些软批处理命令中只对数据库进行了一次实际调用/点击?或者是它分别进行4次点击?
当我从代码中删除.Load()
时,我在SQL事件探查器中得到了这个:
当我拨打以下电话时:
public IQueryable<Participant> GetAllWithAllIncluded()
{
dbSet.Include(p => p.EmailNotices);
dbSet.Include(p => p.EmailTemplatePlaceholders);
dbSet.Include(p => p.Actions);
return dbSet;
}
我在SQL Profiler中得到了这个:
RPC:Completed exec sp_executesql N'SELECT ...
RPC:Completed exec sp_executesql N'SELECT ...
RPC:Completed exec sp_executesql N'SELECT ...
RPC:Completed exec sp_executesql N'SELECT ...
更新1
只是为了澄清一下,在方法返回之后,我添加了几个.Where()子句然后我立即.ToList()它。
更新2
按照建议,我包括where和list代码:
List<Participant> participants = GetFilteredParticipants(repo, model, accountID).ToList();
它所调用的功能:
private IQueryable<Participant> GetFilteredParticipants(ParticipantRepository repo, ParticipantRequestModel model, string accountID)
{
IQueryable<Participant> participants = repo.GetAllWithAllIncluded();
participants = participants.Where(p => p.Transaction.Account.AccountID == accountID || p.Transaction.Account.ParentID == accountID);
if (model.ID != null)
{
participants = participants.Where(p => p.ID == model.ID);
}
if (model.ParticipantIdentifier != null)
{
participants = participants.Where(p => p.ParticipantIdentifier == model.ParticipantIdentifier);
}
if (model.TransactionID != null)
{
participants = participants.Where(p => p.TransactionID == model.TransactionID);
}
... more wheres
participants.Where(p => p.EmailNotices.Any(e => e.ParticipantID == p.ID)).Where(p => p.EmailTemplatePlaceholders.Any(e => e.ParticipantID == p.ID)).Where(p => p.Actions.Any(e => e.ParticipantID == p.ID));
return participants;
}
答案 0 :(得分:3)
尝试
dbSet.Include(p => p.EmailNotices)
.Include(p => p.EmailTemplatePlaceholders)
.Include(p => p.Actions)
.Load();
这应该导致单个数据库访问,使用单个SELECT加载所有数据。
答案 1 :(得分:-1)
当使用预先加载时,Entity Framework将生成一个SQL语句,它将一次性获取所有内容,但是,如果您使用延迟加载,则根据您要获取的内容,它将为每个语句创建单独的sql语句。