c# - 将具有动态数据的多个对象推送到 DTO 中并返回
问题描述
所以我试图使用 DTO 来重塑和返回数据,它不起作用,因为我试图将一组对象(作为 IQueryable - 我认为不起作用)推入 DTO,我是还尝试将动态数据推入属性之一,如下面的“hasCurrentUserLiked”属性所示。我需要弄清楚如何将对象从 IQueryables 更改为实际对象,以便可以将它们全部推送到 DTO 中并且可以计算出动态数据。
这是代码
public async Task<PagedList<UserPhoto>> GetSpecificFeed(UserParams userParams)
{
var user = _context.Users.FirstOrDefault(x => x.Username == userParams.u);
var userId = user.Id;
var photos = _context.UserPhotos;
var followerIds = _context.Follows.Where(x => x.FollowerId == userId).Select(x => x.FollowingId).ToList();
var feeds = _context.UserPhotos.Where(x => followerIds.Contains(x.UserId)).OrderByDescending(x => x.DateAdded);
// this doesn't work because 'feeds' is an IQuerable, not an object
var like = await hasCurrentUserLiked(user.Id, feeds.id);
// this has the same problem as above
var feedsToReturn = new FeedsForReturnDto
{
Id = feeds.Id,
PhotoUrl = feeds.photoUrl,
Username = feeds.Username,
Description = feeds.Description,
DateAdded = feeds.DateAdded,
IsImage = feeds.IsImage,
hasCurrentUserLiked = like,
Likes = feeds.Likes
}
return await PagedList<UserPhoto>.CreateAsync(feedsToReturn, userParams.PageNumber, userParams.PageSize);
}
我认为我可能能够以类似于“followerIds”的方式获取每个 image.id,但我不知道如何让它工作
[编辑]
根据 Enas Osamas 的回答,我已将代码更改为此并对其进行了调试, feedsToReturn 具有正确的信息,因此它正在做它应该做的事情。我现在遇到的问题是我无法返回它,因为它无法将 IEnumerable 转换为 IQueryable。我尝试添加显式演员,但没有奏效,我还尝试删除 PagedList,并将类型替换为,但这不起作用。我的 IQueryable 可能是问题所在,我尝试将其更改为 IEnumerable 但这会弄乱其他地方的代码。
这是我的新代码(仍然返回 'feeds' 而不是 'feedsToReturn',当它工作时会改变)
public async Task<PagedList<UserPhoto>> GetSpecificFeed(UserParams userParams)
{
var user = _context.Users.FirstOrDefault(x => x.Username == userParams.u);
var userId = user.Id;
var photos = _context.UserPhotos;
var followerIds = _context.Follows.Where(x => x.FollowerId == userId).Select(x => x.FollowingId).ToList();
var feeds = _context.UserPhotos.Where(x => followerIds.Contains(x.UserId)).OrderByDescending(x => x.DateAdded);
var feedToReturn = feeds.AsEnumerable().Select(feed => new FeedsForReturnDto
{
Id = feed.Id,
PhotoUrl = feed.photoUrl,
Username = feed.Username,
Description = feed.Description,
DateAdded = feed.DateAdded,
IsImage = feed.IsImage,
hasCurrentUserLiked = hasCurrentUserLiked(user.Id, feed.Id),
Likes = feed.Likes
});
return await PagedList<UserPhoto>.CreateAsync(feeds, userParams.PageNumber, userParams.PageSize);
}
我也尝试改变周围的一些类型,这就是我想出的。这里的问题是:
'System.Collections.Generic.IEnumerable' 到 'System.Linq.IQueryable'
这个问题出在最后一行的“feedsToReturn”上
public async Task<PagedList<IEnumerable>> GetSpecificFeed(UserParams userParams)
{
var user = _context.Users.FirstOrDefault(x => x.Username == userParams.u);
var userId = user.Id;
var photos = _context.UserPhotos;
var followerIds = _context.Follows.Where(x => x.FollowerId == userId).Select(x => x.FollowingId).ToList();
var feeds = _context.UserPhotos.Where(x => followerIds.Contains(x.UserId)).OrderByDescending(x => x.DateAdded);
var feedToReturn = feeds.AsEnumerable().Select(feed => new FeedsForReturnDto
{
Id = feed.Id,
PhotoUrl = feed.photoUrl,
Username = feed.Username,
Description = feed.Description,
DateAdded = feed.DateAdded,
IsImage = feed.IsImage,
hasCurrentUserLiked = hasCurrentUserLiked(user.Id, feed.Id),
Likes = feed.Likes
});
return await PagedList<IEnumerable>.CreateAsync(feedToReturn, userParams.PageNumber, userParams.PageSize);
}
分页列表代码
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);
}
[编辑]
这是 hasCurrentUserLiked 函数,它在这里工作
public bool checkCurrentUserLiked(int currentUserId, int imageId)
{
var doesCurrentUserLike = _context.PhotoLikes.Where(x => x.LikerId == currentUserId && x.ImageId == imageId);
var value = true;
if (doesCurrentUserLike == null)
{
value = false;
}
else
{
value = true;
}
return value;
}
解决方案
你可以尝试类似的东西
feeds.AsEnumerable().Select(feed => new FeedsForReturnDto
{
Id = feed.Id,
PhotoUrl = feed.photoUrl,
Username = feed.Username,
Description = feed.Description,
DateAdded = feed.DateAdded,
IsImage = feed.IsImage,
hasCurrentUserLiked = hasCurrentUserLiked(user.Id, feed.id),
Likes = feed.Likes
});
这将返回一个 IEnumerable,其中包含在枚举后映射到您的 DTO 的所有提要,以避免对数据库执行操作
[编辑]
您也许可以使用 _context.PhotoLikes 进行左连接。像这样
feeds.GroupJoin(_context.PhotoLikes,
f => new { Id = f.Id, UserId = user.Id },
p => new { Id = p.ImageId, UserId = p.LikerId },
(f, p) => new { feed = f, photoLike = p })
.SelectMany(f => f.photoLike.DefaultIfEmpty(),
(f, p) => new FeedsForReturnDto
{
Id = f.feed.Id,
PhotoUrl = f.feed.photoUrl,
Username = f.feed.Username,
Description = f.feed.Description,
DateAdded = f.feed.DateAdded,
IsImage = f.feed.IsImage,
hasCurrentUserLiked = p != null,
Likes = feed.Likes
});
请注意,在这部分
f => new { Id = f.Id, UserId = user.Id },
p => new { Id = p.ImageId, UserId = p.LikerId },
两个对象中属性的数据类型必须匹配,否则无法编译
推荐阅读
- java - 在Java中,在持久化之前解析嵌套对象时获得concurrentModification
- azure - 无法使用数据工厂将多个 BLOB 归档到 Synapse
- mysql - GROUP BY 的 MySQL 键
- javascript - 如何用 puppeteer 抓取 src 图像?
- android - 在 Unity 3d Android 平台中将图像从一个文件夹复制到另一个文件夹
- security - 我可以使用密钥本身计算 RSA 密钥的数据完整性检查吗?
- java - 获取 java.security.InvalidKeyException: Key must be 128, 192, or 256 bit long twofish
- redux - 为什么,在 Redux 中使用 useEffect() 和 .then() 时,我得到一个错误:Actions must be plain objects。使用自定义中间件进行异步操作
- javascript - 为什么 offsetX 和 offsetY 在 Firefox 和 chrome 中返回不同的值
- python - SessionNotCreatedException:会话未创建:此版本的 ChromeDriver 仅支持使用 Selenium 的 Chrome 版本 84