C# 使用IQueryable延迟执行
我正在开发一个简单的映射EntityFramework DTO,它运行良好,除了延迟执行之外,我有以下代码:C# 使用IQueryable延迟执行,c#,entity-framework,automapper,dto,mapper,C#,Entity Framework,Automapper,Dto,Mapper,我正在开发一个简单的映射EntityFramework DTO,它运行良好,除了延迟执行之外,我有以下代码: public abstract class Assembler<TDto, TEntity> : IAssembler<TDto, TEntity> where TEntity : EntityBase , new () where TDto : DtoBase, new () { public abstract TDto Assemble
public abstract class Assembler<TDto, TEntity> : IAssembler<TDto, TEntity>
where TEntity : EntityBase , new ()
where TDto : DtoBase, new ()
{
public abstract TDto Assemble(TEntity domainEntity);
public abstract TEntity Assemble(TEntity entity, TDto dto);
public virtual IQueryable<TDto> Assemble(IQueryable<TEntity> domainEntityList)
{
List<TDto> dtos = Activator.CreateInstance<List<TDto>>();
foreach (TEntity domainEntity in domainEntityList)
{
dtos.Add(Assemble(domainEntity));
}
return dtos.AsQueryable();
}
public virtual IQueryable<TEntity> Assemble(IQueryable<TDto> dtoList)
{
List<TEntity> domainEntities = Activator.CreateInstance<List<TEntity>>();
foreach (TDto dto in dtoList)
{
domainEntities.Add(Assemble(null, dto));
}
return domainEntities.AsQueryable();
}
}
公共抽象类汇编程序:IAssembler
其中tenty:EntityBase,新()
其中TDto:DtoBase,new()
{
公共抽象TDO集合(TEntity domainEntity);
公共抽象能力集合(能力实体,TDto dto);
公共虚拟IQueryable汇编(IQueryable domainEntityList)
{
List dtos=Activator.CreateInstance();
foreach(domainEntityList中的TEntity domainEntity)
{
添加(汇编(域实体));
}
返回dtos.AsQueryable();
}
公共虚拟IQueryable汇编(IQueryable dtoList)
{
List domainEntities=Activator.CreateInstance();
foreach(dtoList中的TDto dto)
{
Add(汇编(null,dto));
}
返回domainEntities.AsQueryable();
}
}
示例汇编程序:
public partial class BlogEntryAssembler : Assembler<BlogEntryDto, BlogEntry>, IBlogEntryAssembler
{
public override BlogEntry Assemble(BlogEntry entity, BlogEntryDto dto)
{
if (entity == null)
{
entity = new BlogEntry();
}
/*
entity.Id = dto.Id;
entity.Created = dto.Created;
entity.Modified = dto.Modified;
entity.Header = dto.Header;
*/
base.MapPrimitiveProperties(entity, dto);
this.OnEntityAssembled(entity);
return entity;
}
public override BlogEntryDto Assemble(BlogEntry entity)
{
BlogEntryDto dto = new BlogEntryDto();
//dto.Id = entity.Id;
//dto.Modified = entity.Modified;
//dto.Created = entity.Created;
//dto.Header = entity.Header;
base.MapPrimitiveProperties(dto, entity);
dto.CategoryName = entity.Category.Name;
dto.AuthorUsername = entity.User.Username;
dto.AuthorFirstName = entity.User.FirstName;
dto.AuthorLastName = entity.User.LastName;
dto.TagNames = entity.Tags.Select(t => t.Name)
.ToArray();
dto.TagIds = entity.Tags.Select(t => t.Id)
.ToArray();
dto.VotedUpUsernames = entity.BlogEntryVotes.Where(v => v.Vote > 0)
.Select(t => t.User.Username)
.ToArray();
dto.VotedDownUsernames = entity.BlogEntryVotes.Where(v => v.Vote < 0)
.Select(t => t.User.Username)
.ToArray();
// Unmapped
dto.FileCount = entity.BlogEntryFiles.Count();
dto.CommentCount = entity.BlogEntryComments.Count();
dto.VisitCount = entity.BlogEntryVisits.Count();
dto.VoteCount = entity.BlogEntryVotes.Count();
dto.VoteUpCount = entity.BlogEntryVotes.Count(v => v.Vote.Equals(1));
dto.VoteDownCount = entity.BlogEntryVotes.Count(v => v.Vote.Equals(-1));
dto.VotePuntuation = entity.BlogEntryVotes.Sum(v => v.Vote);
dto.Published = entity.Visible && entity.PublishDate <= DateTime.Now;
this.OnDTOAssembled(dto);
return dto;
}
}
public分部类BlogEntryAssembler:Assembler,IBlogEntryAssembler
{
公共重写BlogEntry汇编(BlogEntry实体,BlogEntryDto)
{
if(实体==null)
{
entity=newblogentry();
}
/*
entity.Id=dto.Id;
entity.Created=dto.Created;
实体修改=数据修改;
entity.Header=dto.Header;
*/
base.MapPrimitiveProperties(实体,dto);
这是一个集合(实体);
返回实体;
}
公共重写BlogEntryDto汇编(BlogEntry实体)
{
BlogEntryDto dto=新的BlogEntryDto();
//dto.Id=entity.Id;
//dto.Modified=实体.Modified;
//dto.Created=实体.Created;
//dto.Header=实体.Header;
base.MapPrimitiveProperties(dto,实体);
dto.CategoryName=entity.Category.Name;
dto.AuthorUsername=entity.User.Username;
dto.AuthorFirstName=entity.User.FirstName;
dto.AuthorLastName=entity.User.LastName;
dto.TagNames=entity.Tags.Select(t=>t.Name)
.ToArray();
dto.TagIds=entity.Tags.Select(t=>t.Id)
.ToArray();
dto.VotedUpUsernames=entity.blogentrydoves.Where(v=>v.Vote>0)
.Select(t=>t.User.Username)
.ToArray();
dto.VotedDownUsernames=entity.blogentrydoves.Where(v=>v.Vote<0)
.Select(t=>t.User.Username)
.ToArray();
//未映射
dto.FileCount=entity.BlogEntryFiles.Count();
dto.CommentCount=entity.blogentrycoments.Count();
dto.VisitCount=entity.BlogEntryVisits.Count();
dto.VoteCount=entity.blogentrydoves.Count();
dto.VoteUpCount=entity.blogentrydoves.Count(v=>v.Vote.Equals(1));
dto.VoteDownCount=entity.blogentrydoves.Count(v=>v.Vote.Equals(-1));
dto.votePantuation=entity.blogentrydoves.Sum(v=>v.Vote);
dto.Published=entity.Visible&&entity.PublishDate b.Tags)
.Include(b=>b.User)
.包括(b=>b.类别)
.Include(b=>b.BlogEntryFiles)
.Include(b=>b.BlogEntryComments)
.Include(b=>b.BlogEntryPingbacks)
.Include(b=>b.blogentryvisions)
.Include(b=>b.blogentrydowes)
.Include(b=>b.BlogEntryImages)
.AsNoTracking();
如果(!includeInvisibleEntries)
{
条目=条目。其中(e=>e.Visible);
}
如果(!string.IsNullOrEmpty(类别))
{
entries=entries.Where(e=>e.Category.Name.Equals(Category,StringComparison.OrdinalIgnoreCase));
}
如果(!string.IsNullOrEmpty(标记))
{
entries=entries.Where(e=>e.Tags.Count(t=>t.Name.Equals(tag,StringComparison.OrdinalIgnoreCase))>0);
}
如果(!string.IsNullOrEmpty(搜索))
{
foreach(search.Split中的变量项(新字符[]{''},StringSplitOptions.RemoveEmptyEntries))
{
条目=条目。其中(e=>e.Header.Contains(item));
}
}
返回this.Assembler.assembly(条目).GetPagedResult(分页);
}
当我调用GetAll方法时,它返回并将表中的所有实体转换为Dto,然后才分页生成的集合,当然这不是我所期望的。我希望在分页完成后在Assemble方法中执行代码,知道吗
PS:我知道我可以使用Automapper,只是试着学习内部结构。公共虚拟IQueryable汇编(IQueryable domainEntityList)
public virtual IQueryable<TDto> Assemble(IQueryable<TEntity> domainEntityList)
{
List<TDto> dtos = Activator.CreateInstance<List<TDto>>();
foreach (TEntity domainEntity in domainEntityList)
{
dtos.Add(Assemble(domainEntity));
}
return dtos.AsQueryable();
}
{
List dtos=Activator.CreateInstance();
foreach(domainEntityList中的TEntity domainEntity)
{
添加(汇编(域实体));
}
返回dtos.AsQueryable();
}
上面代码中的foreach循环是在数据库服务器上执行查询的点
从这一行可以看出:
返回this.Assembler.assembly(条目).GetPagedResult(分页)
此方法在GetPagedResult(分页)之前被调用…这就是分页在整个结果集上发生的原因
您应该了解枚举查询(foreach)需要运行查询。foreach循环处理该查询返回的每条记录。现在分页方法停止它已经太晚了!公共虚拟IQueryable汇编(IQueryable domainEntityList)
{
List dtos=Activator.CreateInstance();
foreach(domainEntityList中的TEntity domainEntity)
{
添加(汇编(域实体));
}
返回dtos.AsQueryable();
}
上面代码中的foreach循环是在数据库服务器上执行查询的点
从这一行可以看出:
返回this.Assembler.assembly(条目).GetPagedResult(分页)
<
public virtual IQueryable<TDto> Assemble(IQueryable<TEntity> domainEntityList)
{
List<TDto> dtos = Activator.CreateInstance<List<TDto>>();
foreach (TEntity domainEntity in domainEntityList)
{
dtos.Add(Assemble(domainEntity));
}
return dtos.AsQueryable();
}