首页 > 解决方案 > 将具有动态数据的多个对象推送到 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;
    }

标签: c#.net-core

解决方案


你可以尝试类似的东西

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 },

两个对象中属性的数据类型必须匹配,否则无法编译


推荐阅读