我们的context.Configuration.LazyLoadingEnabled = false;
这是我的参考:http://www.entityframeworktutorial.net/EntityFramework4.3/explicit-loading-with-dbcontext.aspx
我们的API中有一个方法可以获得一个包含所有子节点的实体:
[IsQuery]
[HttpGet]
public async Task<IEnumerable<Blog>> GetAllBlogs()
{
return this.EntityProvider.Get(this.CachedReader, BlogCore.AllIncludes);
}
这些是包含的导航属性
public static Expression<Func<Blog, object>>[] AllIncludes = new Expression<Func<Blog, object>>[]
{
i => i.Community.Name,
i => i.Categories.Select(c => c.Children),
i => i.Categories.Select(c => c.Name),
i => i.Categories.Select(c => c.Description),
i => i.Submitter,
i => i.Champion,
i => i.Properties,
i => i.Challenge.Name,
i => i.Challenge.Description,
i => i.Challenge.RestrictToSubmit,
i => i.Challenge.Prize,
i => i.Status.Name,
i => i.Tags,
i => i.Contributors,
i => i.Watchers,
i => i.Documents.Select(d => d.Form.Name),
i => i.Documents.Select(d => d.Form.Fields.Select(f => f.Metadata)),
i => i.Documents.Select(d => d.Responses.Select(r => r.Field.Metadata)),
i => i.Documents.Select(d => d.Responses.Select(r => r.BlobReferences.Select(b => b.Blob))),
i => i.StatusComments.Select(s => s.User),
i => i.StatusComments.Select(s => s.Status.Name),
i => i.StatusComments.Select(s => s.Status.StatusIcon.Blob),
i => i.BlogThumb,
i => i.BlogThumb.Blob
};
我们也有映射类
public override void ExtendDomainModel([NotNull] IRepositoryMetadata metadata, [NotNull] EntityTypeConfiguration<Blog> map)
{
map.Property(p => p.DateSubmitted).IsRequired();
map.Property(p => p.LastEdited).IsRequired();
map.HasRequired(p => p.Status);
map.HasRequired(p => p.Community);
map.HasOptional(p => p.Challenge);
map.HasOptional(p => p.Champion);
map.HasRequired(p => p.Submitter);
map.MapManyToMany(metadata, p => p.Contributors, "blogContributor", "blogID", "userID");
map.MapManyToMany(metadata, p => p.Tags, "blogTag", "blogID", "tagID");
map.MapManyToMany(metadata, p => p.Categories, "blogCategories", "blogID", "categoryID");
map.MapManyToMany(metadata, p => p.Watchers, "blogWatchers", "blogID", "userID");
map.MapManyToMany(metadata, p => p.Documents, "blogdocument", "blogID", "responseID");
map.HasMany(p => p.StatusComments).WithRequired(p => p.Blog);
map.HasAddedProperties(metadata, "blogProperty");
map.HasOptional(p => p.BlogThumb).WithOptionalDependent().WillCascadeOnDelete();
}
我的查询需要4秒。没有Categories
和Documents
以及StatusComments
这些需要20秒。在本地机器上。
使用SQL profiler我注意到有很多子查询获得二级属性。我想省略子查询。
然后转到通用方法并添加所有包含子项:
[NotNull]
public IQueryable<TEntity> Get(ICacheableReader reader, params Expression<Func<TEntity, object>>[] includes)
{
return reader.Get<TEntity>(opt => opt.Include(includes));
}
/// <summary>Construct a query which retrieves all entities from the repository.</summary>
/// <typeparam name="TEntity">The entity type.</typeparam>
/// <param name="options">The entity query configuration.</param>
/// <returns>Returns a deferred query.</returns>
/// <exception cref="ObjectDisposedException">This reader has been disposed.</exception>
public IQueryable<TEntity> Get<TEntity>(Action<IQueryConfig<TEntity>> options = null) where TEntity : class, IEntity
{
this.AssertAccessible();
return this.ApplyOptions(this.Context.Set<TEntity>(), options);
}
答案 0 :(得分:2)
类似(对于第一级属性):
public IQueryable<TEntity> Get<TEntity>(
Action<IQueryConfig<TEntity>> options = null,
IEnumerable<Expression<Func<TEntity, Object>>> includeProperties = null) where TEntity : class, IEntity
{
this.AssertAccessible();
IQueryable<TEntity> query = this.Context.Set<TEntity>();
if ( includeProperties != null )
query = includeProperties.Aggregate(query, (current, includeProperty) => current.Include(includeProperty));
return this.ApplyOptions(query, options);
}