C# QueryableExtensions ProjectTo不投影地图
在内存中结合使用automapper 5.2.0、EF core 1.0.1和SQL lite。我无法让它创建预期的数据库查询,而是得到以下结果: Microsoft.EntityFrameworkCore.Query.RelationalQueryCompilationContextFactory:警告: 导航的包含操作:“a.PostTags.Tag”被忽略 因为在最终查询中无法访问目标导航 结果。要配置此警告,请使用 DBContextOptions Builder.ConfigureWarnings API(事件id “CoreEventId.IncludeIgnoredWarning”)。可以使用配置警告 重写DbContext.onconfig方法或使用 应用程序服务提供程序上的AddDbContext。 Microsoft.EntityFrameworkCore.Query.RelationalQueryCompilationContextFactory:警告: 导航“a.Responses.CreatedByUser”的包含操作被删除 已忽略,因为最终用户无法访问目标导航 查询结果。要配置此警告,请使用 DBContextOptions Builder.ConfigureWarnings API(事件id “CoreEventId.IncludeIgnoredWarning”)。可以使用配置警告 重写DbContext.onconfig方法或使用 应用程序服务提供程序上的AddDbContext。 Microsoft.EntityFrameworkCore.Query.RelationalQueryCompilationContextFactory:警告: 导航的包含操作:“a.CreatedByUser”被忽略 因为在最终查询中无法访问目标导航 结果。要配置此警告,请使用 DBContextOptions Builder.ConfigureWarnings API(事件id “CoreEventId.IncludeIgnoredWarning”)。可以使用配置警告 重写DbContext.onconfig方法或使用 应用程序服务提供程序上的AddDbContext。 Microsoft.EntityFrameworkCore.Query.RelationalQueryCompilationContextFactory:警告: 导航的包含操作:“a.Category”被忽略,因为 在最终查询结果中无法访问目标导航。到 使用以下命令配置此警告: DBContextOptions Builder.ConfigureWarnings API(事件id “CoreEventId.IncludeIgnoredWarning”)。可以使用配置警告 重写DbContext.onconfig方法或使用 应用程序服务提供程序上的AddDbContext。 Microsoft.EntityFrameworkCore.Storage.IRelationalCommandBuilderFactory:信息: 已执行的DbCommand(0ms)[参数=[@_id_0='?'], CommandType='Text',CommandTimeout='30']从“Posts”中选择1作为“a” 其中“a”。“PostId”=@\uu id\u 0限制2 以下是我的设置: 启动:C# QueryableExtensions ProjectTo不投影地图,c#,automapper,entity-framework-core,projection,C#,Automapper,Entity Framework Core,Projection,在内存中结合使用automapper 5.2.0、EF core 1.0.1和SQL lite。我无法让它创建预期的数据库查询,而是得到以下结果: Microsoft.EntityFrameworkCore.Query.RelationalQueryCompilationContextFactory:警告: 导航的包含操作:“a.PostTags.Tag”被忽略 因为在最终查询中无法访问目标导航 结果。要配置此警告,请使用 DBContextOptions Builder.ConfigureWa
public class Startup
{
private MapperConfiguration _mapperConfiguration { get; set; }
public Startup(IHostingEnvironment env)
{
...
_mapperConfiguration = new MapperConfiguration(cfg =>
{
...
cfg.AddProfile(new PostMapperProfile());
});
_mapperConfiguration.AssertConfigurationIsValid();
}
public void ConfigureServices(IServiceCollection services)
{
...
services.AddSingleton<IMapper>(sp => _mapperConfiguration.CreateMapper());
services.AddSingleton<MapperConfiguration>(sp => _mapperConfiguration);
}
}
公共类启动
{
私有MapperConfiguration\u MapperConfiguration{get;set;}
公共启动(IHostingEnvironment环境)
{
...
_mapperConfiguration=新的mapperConfiguration(cfg=>
{
...
AddProfile(新的PostApperProfile());
});
_mapperConfiguration.AssertConfigurationsValid();
}
public void配置服务(IServiceCollection服务)
{
...
services.AddSingleton(sp=>\u mappeConfiguration.CreateMapper());
services.AddSingleton(sp=>\u mapperConfiguration);
}
}
PostApperProfile:
public class PostMapperProfile : Profile
{
public PostMapperProfile()
{
var postDetailMap = CreateMap<PostEntity, PostDetailModel>();
postDetailMap.ForAllMembers(opt => opt.Ignore());
postDetailMap.ForMember(m => m.Category, opt => opt.MapFrom(src => src.CategoryId.HasValue ? src.Category : null));
postDetailMap.ForMember(m => m.CreatedAt, opt => opt.MapFrom(src => src.CreatedAt));
postDetailMap.ForMember(m => m.CreatedByUser, opt => opt.MapFrom(src => src.CreatedByUser));
postDetailMap.ForMember(m => m.PostId, opt => opt.MapFrom(src => src.PostId));
postDetailMap.ForMember(m => m.PostState, opt => opt.MapFrom(src => src.PostState));
postDetailMap.ForMember(m => m.PostType, opt => opt.MapFrom(src => src.PostType));
postDetailMap.ForMember(m => m.ResponsesCount, opt => opt.MapFrom(src => src.Responses.Count));
postDetailMap.ForMember(m => m.Text, opt => opt.MapFrom(src => src.Text));
postDetailMap.ForMember(m => m.Tags, opt => opt.MapFrom(src => src.PostTags.Select(x => x.Tag).ToList()));
postDetailMap.ForMember(m => m.Title, opt => opt.MapFrom(src => src.Title));
postDetailMap.ForMember(m => m.ViewsCount, opt => opt.MapFrom(src => src.ViewsCount));
postDetailMap.ForMember(m => m.VotesCount, opt => opt.MapFrom(src => src.VotesCount));
postDetailMap.ForMember(m => m.Responses, opt => opt.MapFrom(src => PagedList<ResponseEntity>.Create(src.Responses.Take(10).Select(x => AutoMapper.Mapper.Map<ResponseDetailModel>(x)).ToList(), 1, 10, src.Responses.Count)));
}
}
public类PostMapperProfile:Profile
{
公共邮递表格()
{
var postDetailMap=CreateMap();
ForAllMembers(opt=>opt.Ignore());
postDetailMap.FormMember(m=>m.Category,opt=>opt.MapFrom(src=>src.CategoryId.HasValue?src.Category:null));
postDetailMap.FormMember(m=>m.CreatedAt,opt=>opt.MapFrom(src=>src.CreatedAt));
postDetailMap.formMember(m=>m.CreatedByUser,opt=>opt.MapFrom(src=>src.CreatedByUser));
postDetailMap.formMember(m=>m.PostId,opt=>opt.MapFrom(src=>src.PostId));
ForMember(m=>m.PostState,opt=>opt.MapFrom(src=>src.PostState));
postDetailMap.formMember(m=>m.PostType,opt=>opt.MapFrom(src=>src.PostType));
postDetailMap.FormMember(m=>m.responseCount,opt=>opt.MapFrom(src=>src.Responses.Count));
ForMember(m=>m.Text,opt=>opt.MapFrom(src=>src.Text));
ForMember(m=>m.Tags,opt=>opt.MapFrom(src=>src.PostTags.Select(x=>x.Tag.ToList());
postDetailMap.formMember(m=>m.Title,opt=>opt.MapFrom(src=>src.Title));
postDetailMap.formMember(m=>m.viewsunt,opt=>opt.MapFrom(src=>src.viewsunt));
postDetailMap.FormMember(m=>m.VotesCount,opt=>opt.MapFrom(src=>src.VotesCount));
postDetailMap.FormMember(m=>m.Responses,opt=>opt.MapFrom(src=>PagedList.Create(src.Responses.Take(10).Select(x=>AutoMapper.Mapper.Map(x)).ToList(),1,10,src.Responses.Count));
}
}
博客邮政服务:
public class BlogpostService
{
private readonly AppDbContext m_context;
private readonly IMapper m_mapper;
private readonly MapperConfiguration m_config;
public BlogpostService(AppDbContext context, IMapper mapper, MapperConfiguration config)
{
m_context = context;
m_mapper = mapper;
m_config = config;
}
public PostDetailModel GetPostDetail(int id)
{
var s = m_context.Posts
.Include(a => a.CreatedByUser)
.Include(a => a.Category)
.Include(a => a.PostTags)
.ThenInclude(a => a.Tag)
.Include(a => a.Responses)
.ThenInclude(b => b.CreatedByUser)
.Where(x => x.PostId == id);
var d = s.Single();
return s.ProjectTo<PostDetailModel>(m_config).Single();
}
}
公共类BlogpostService
{
私有只读AppDbContext m_context;
专用只读映像映射器;
私有只读MapperConfiguration m_config;
公共BlogpostService(AppDbContext上下文、IMapper映射器、MapperConfiguration配置)
{
m_context=上下文;
m_mapper=映射器;
m_config=config;
}
公共PostDetailModel GetPostDetail(int id)
{
var s=m_context.Posts
.Include(a=>a.CreatedByUser)
.Include(a=>a.Category)
.Include(a=>a.PostTags)
.然后包括(a=>a.Tag)
.Include(a=>a.Responses)
.然后包括(b=>b.CreatedByUser)
。其中(x=>x.PostId==id);
var d=s.Single();
返回s.ProjectTo(m_config).Single();
}
}
测试:
公共类PostRepositoryTests
{
公共测试服务器服务器{get;}
公共HttpClient客户端{get;}
私有只读AppDbContext上下文;
私有只读用户管理器用户管理器;
专用只读IMapper映射器;
私有只读MapperConfiguration配置;
公共存储后测试()
{
...
上下文=ser
public class PostRepositoryTests
{
public TestServer server { get; }
public HttpClient client { get; }
private readonly AppDbContext Context;
private readonly UserManager<UserEntity> UserManager;
private readonly IMapper Mapper;
private readonly MapperConfiguration Config;
public PostRepositoryTests()
{
...
Context = serviceProvider.GetRequiredService<AppDbContext>();
UserManager = serviceProvider.GetRequiredService<UserManager<UserEntity>>();
Mapper = serviceProvider.GetService<IMapper>();
Config = serviceProvider.GetService<MapperConfiguration>();
}
[Fact]
public void CreatePost()
{
var user = new UserEntity();
user.Email = "test@test.com";
var ct = UserManager.CreateAsync(user, "Testing123..");
var service = new BlogpostService(Context, Mapper, Config);
var blogpost = new CreateBlogpostRequest();
blogpost.Title = "Some title";
blogpost.Content = "Some content";
blogpost.Tags = new List<TagDTO>(){
new TagDTO{
Label = "Tag1",
},
new TagDTO{
Label = "Tag2",
},
new TagDTO{
Label = "Tag3",
}
};
var response = service.CreateBlogpost(blogpost, user.Id);
var postDetail = service.GetPostDetail(response.PostId);
Assert.Equal(postDetail.Tags.Count, 3);
}
}
postDetailMap.ForAllMembers(opt => opt.Ignore());
var postDetailMap = CreateMap<PostEntity, PostDetailModel>();
postDetailMap.ForMember(m => m.ResponsesShowing,opt => opt.Ignore());
postDetailMap.ForMember(m => m.Responses, opt => opt.Ignore());
// postDetailMap.ForAllMembers(opt => opt.Ignore());
postDetailMap.ForMember(m => m.Category, opt => opt.MapFrom(src => src.CategoryId.HasValue ? src.Category : null));
postDetailMap.ForMember(m => m.CreatedAt, opt => opt.MapFrom(src => src.CreatedAt));
postDetailMap.ForMember(m => m.CreatedByUser, opt => opt.MapFrom(src => src.CreatedByUser));
postDetailMap.ForMember(m => m.PostId, opt => opt.MapFrom(src => src.PostId));
postDetailMap.ForMember(m => m.PostState, opt => opt.MapFrom(src => src.PostState));
postDetailMap.ForMember(m => m.PostType, opt => opt.MapFrom(src => src.PostType));
postDetailMap.ForMember(m => m.ResponsesCount, opt => opt.MapFrom(src => src.Responses.Count));
postDetailMap.ForMember(m => m.Text, opt => opt.MapFrom(src => src.Text));
postDetailMap.ForMember(m => m.Tags, opt => opt.MapFrom(src => src.PostTags.Select(x => x.Tag)));
postDetailMap.ForMember(m => m.Title, opt => opt.MapFrom(src => src.Title));
postDetailMap.ForMember(m => m.ViewsCount, opt => opt.MapFrom(src => src.ViewsCount));
postDetailMap.ForMember(m => m.VotesCount, opt => opt.MapFrom(src => src.VotesCount));
//postDetailMap.ForMember(m => m.Responses, opt => opt.MapFrom(src => PagedList<ResponseEntity>.Create(src.Responses.Take(10).Select(x => AutoMapper.Mapper.Map<ResponseDetailModel>(x)).ToList(), 1, 10, src.Responses.Count)));