首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将讨论项从SQL-View映射到对象

将讨论项从SQL-View映射到对象
EN

Code Review用户
提问于 2016-04-19 15:37:18
回答 1查看 46关注 0票数 1

在我的ASP.NET MVC应用程序中,我加载讨论条目记录以及用户信息(谁发布了条目)、徽章(分配给条目)、反应(对条目进行了类似Facebook风格的反应)。我通过存储过程(在实体框架内执行)从SQL( 23列)检索这些记录。每次我只检索前10个条目(以及所有相关的数据)。

然后,我将这些项(具有23个属性)正确映射到对象中,并在页面上显示它们:

讨论条目1内容用户: Name1 Surname1徽章: B51,B12,B23.反应: R1,R32,R3.回复讨论条目1(这实际上也是讨论条目)用户: Name5 Surname5徽章: B1,B6,B3反应: R1,R12,R3.内容用户: Name2 Surname2徽章: B1,B2,B3.反应: R1,R2,R3.

但是,我需要有几个循环来正确地加载每个条目的徽章和反应列表对象。我意识到这消耗了太多的内存(200 too )和处理器能力。我认为发出单个db调用将是最有效的,而不是进行多个db调用。然而,这似乎不起作用。你认为我的代码效率低下,需要修改吗?

代码语言:javascript
复制
var entryviews = db.Database.SqlQuery<ViewEntryRecord>("CALL TO THE STORED PROCEDURE").ToList();            

foreach (var entryview in entryviews)
{

        var entryitem = new Entry()
        {
            EntryId = entryview.EntryId,
            Date = entryview.Date,
            Title = entryview.Title,
            Content = entryview.Content,
            ParentEntryId = entryview.ParentEntryId,
            EntryDepthness = entryview.EntryDepthness,
            IsAnonymous = entryview.IsAnonymous,
            IsHighlighted = entryview.IsHighlighted,
            IsPinned = entryview.IsPinned,
            ChildCount = entryview.ChildCount,
            FirstDescendantCount = entryview.FirstDescendantCount,
            User = new ApplicationUser
            {
                Id = entryview.UserId,
                FirstName = entryview.FirstName,
                LastName = entryview.LastName,
                AnonymousName = entryview.AnonymousName,
                AnonymousPhoto = entryview.AnonymousPhoto,
                ProfilePhoto = entryview.ProfilePhoto,
            }
        };
        entryitem.Badges = new List<BadgeAssignment>();
        List<int> recordedBadgeIds = new List<int>();

        foreach (var item in entryviews.Where(ew => ew.EntryId == entryview.EntryId && ew.BadgeId != null))
        {
            if (!recordedBadgeIds.Contains((int)item.BadgeId))
            {
                var bdg = new BadgeAssignment
                {
                    BadgeId = (int)item.BadgeId,
                    BadgeAssociated = new Badge
                    {
                        BadgeId = (int)item.BadgeId,
                        BadgeName = item.BadgeName,
                        Description = item.BadgeDescription
                    }
                };

                entryitem.Badges.Add(bdg);

                recordedBadgeIds.Add((int)item.BadgeId);
            }
        }

        entryitem.ReactionsToEntry = new List<ReactionToEntry>();
        List<string> recordedReactionIdUserIds = new List<string>();
        foreach (var item in entryviews.Where(ew => ew.EntryId == entryview.EntryId && ew.ReactionId != null))
        {
            if (!recordedReactionIdUserIds.Contains(item.ReactionId + "." + item.RTEUserId))
            {
                var rte = new ReactionToEntry
                {
                    ReactionId = (int)item.ReactionId,
                    EntryId = entryitem.EntryId,
                    UserId = item.RTEUserId
                };
                entryitem.ReactionsToEntry.Add(rte);
                recordedReactionIdUserIds.Add(item.ReactionId + "." + item.RTEUserId);
            }
        }

        if (!entries.Any(ent => ent.EntryId == entryitem.EntryId))
            entries.Add(entryitem);

}
EN

回答 1

Code Review用户

回答已采纳

发布于 2016-04-19 16:08:49

代码语言:javascript
复制
if (!entries.Any(ent => ent.EntryId == entryitem.EntryId))
    entries.Add(entryitem);  

不应该放在循环的底部。相反,在创建Entry之前,您应该检查entries中是否有Entry,如果有,则只需检查continue。您的代码应该只做它需要做的工作。

对于每一项,您将对整个视图进行额外的两次迭代,这并不是非常必要的。您应该从entryviews中提取一个集合,该集合只包含ew => ew.EntryId == entryview.EntryId所在的项,然后对BadgeAssignmentReactionToEntry进行如下过滤

代码语言:javascript
复制
var currentEntries = entryviews.Where(ew => ew.EntryId == entryview.EntryId).ToList();

....

foreach (var item in currentEntries.Where(ew.BadgeId != null))
{
    if (!recordedBadgeIds.Contains((int)item.BadgeId))
    {
        var bdg = new BadgeAssignment
        {
            BadgeId = (int)item.BadgeId,
            BadgeAssociated = new Badge
            {
                BadgeId = (int)item.BadgeId,
                BadgeName = item.BadgeName,
                Description = item.BadgeDescription
            }
        };

        entryitem.Badges.Add(bdg);

        recordedBadgeIds.Add((int)item.BadgeId);
    }
}

我鼓励您始终使用大括号{},尽管它们可能是可选的。这有助于降低代码的易出错性(例如,错误)和更好的结构化,从而提高可读性。

你的编码风格不一致。一次使用(),尽管使用对象初始化(请参阅var entryitem),另一次则忽略它们(参见User = new ApplicationUser)。

切换样式是一个坏习惯,应该避免,以提高代码的可读性。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/126130

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档