繁体   English   中英

将具有动态数据的多个对象推送到 DTO 中并返回

[英]Push multiple objects with dynamic data into a DTO and return it

所以我试图使用 DTO 来重塑和返回数据,它不起作用,因为我试图将一组对象(作为IQueryable - 我认为不起作用)推入 DTO,我是还尝试将动态数据推入属性之一,如下面的“hasCurrentUserLiked”属性所示。 我需要弄清楚如何将对象从IQueryable更改为实际对象,以便可以将它们全部推入 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 IQueryable, 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<cartalk.api.Dtos.feeds.FeedsForReturnDto>' to 'System.Linq.IQueryable<System.Collections.IEnumerable>'

这个问题出在最后一行的“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 function,它在这里工作

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM