在我的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调用。然而,这似乎不起作用。你认为我的代码效率低下,需要修改吗?
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);
}发布于 2016-04-19 16:08:49
这
if (!entries.Any(ent => ent.EntryId == entryitem.EntryId))
entries.Add(entryitem); 不应该放在循环的底部。相反,在创建Entry之前,您应该检查entries中是否有Entry,如果有,则只需检查continue。您的代码应该只做它需要做的工作。
对于每一项,您将对整个视图进行额外的两次迭代,这并不是非常必要的。您应该从entryviews中提取一个集合,该集合只包含ew => ew.EntryId == entryview.EntryId所在的项,然后对BadgeAssignment和ReactionToEntry进行如下过滤
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)。
切换样式是一个坏习惯,应该避免,以提高代码的可读性。
https://codereview.stackexchange.com/questions/126130
复制相似问题