我有兩個物體,AppUser并且InterestTag:
public class AppUser : IdentityUser<int>
{
public ICollection<InterestTag> InterestTags { get; set; }
}
public class InterestTag
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<AppUser> AppUsers { get; set; }
}
它們被配置為DataContext具有直接的多對多關系
builder.Entity<AppUser>()
.HasMany(u => u.InterestTags)
.WithMany(ut => ut.AppUsers);
我正在嘗試創建一種方法,InterestTags通過用戶的用戶名獲取用戶的所有資訊,然后將其投影InterestTag到 aInterestTagDto并對結果進行分頁。
InterestTagDto:_
public class InterestTagDto
{
public int Id { get; set; }
public string Name { get; set; }
}
映射配置為
CreateMap<InterestTag, InterestTagDto>();
PagedList班級:
public class PagedList<T> : List<T>
{
public PagedList(IEnumerable<T> items, int count, int pageNumber, int pageSize)
{
CurrentPage = pageNumber;
TotalPages = (int)Math.Ceiling(count / (double)pageSize);
PageSize = pageSize;
TotalCount = count;
AddRange(items);
}
public int CurrentPage { get; set; }
public int TotalPages { get; set; }
public int PageSize { get; set; }
public int TotalCount { get; set; }
public static async Task<PagedList<T>> CreateAsync(IQueryable<T> source, int pageNumber, int pageSize)
{
var count = await source.CountAsync();
var items = await source.Skip((pageNumber - 1) * pageSize).Take(pageSize).ToListAsync();
return new PagedList<T>(items, count, pageNumber, pageSize);
}
}
我到目前為止的方法:
public async Task<PagedList<InterestTagDto>> GetUserInterestTagsAsync(string username)
{
var query = (await _context.Users.Include(u => u.InterestTags).SingleOrDefaultAsync(u => u.UserName == username)).InterestTags.AsQueryable();
return await PagedList<InterestTagDto>.CreateAsync(query.ProjectTo<InterestTagDto>(_mapper.ConfigurationProvider)
.AsNoTracking(), 1, 20);
}
在線上
var count = await source.CountAsync();
的PagedList<>,我得到一個錯誤
源“IQueryable”的提供程式未實作“IAsyncQueryProvider”。只有實作“IAsyncQueryProvider”的提供程式才能用于物體框架異步操作
我認為問題在于,在它映射到 DTO 之后,它的型別是 HashSet:
{System.Collections.Generic.HashSet`1[API.Entities.InterestTag].Select(dtoInterestTag => new InterestTagDto() {Id = dtoInterestTag.Id, Name = dtoInterestTag.Name})}
我有一個類似的函式,它可以獲取串列AppUsers并將其映射到 aMemberDto并使用相同的PagedList類。
映射后的型別為:
{Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable<API.DTOs.MemberDto>}
任何幫助深表感謝。謝謝!
uj5u.com熱心網友回復:
問題出在您的“查詢”中(實際上不是查詢,而是具體化的查詢結果):
var query = (await _context.Users.Include(u => u.InterestTags).SingleOrDefaultAsync(u => u.UserName == username)).InterestTags.AsQueryable();
您正在使用實作查詢,SingleOrDefaultAsync因此 EF 將呼叫資料庫并使用 .NET 類和集合將資料映射到記憶體,從而使AppUser.InterestTags某些集合和內置集合通常無法實作IAsyncQueryProvider,這會導致您面臨的錯誤。
有幾種可能的解決方法:
創建
PagedList.CreateAsync接受IEnumerable并將查詢結果作為普通可列舉而不是可查詢的多載。重寫查詢,使其實際上是一個查詢。像這樣的東西:
var query = await _context.Users
.Where(u => u.UserName == username)) // assuming UserName is unique
.SelectMany(t => t.InterestTags);
// pass to CreateAsync ...
附言
通常也盡量防止過度獲取(您只需InterestTags要從資料庫中獲取User表中的其余用戶資料,盡管它不會導致提供的錯誤)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/471022.html
