gpt4 book ai didi

c# - ASP .NET 获取数据太慢

转载 作者:太空宇宙 更新时间:2023-11-03 12:37:23 25 4
gpt4 key购买 nike

我目前正在使用 ASP.NET MVC 和 Angular 开发网络应用程序。我想要做的是根据每个用户的 Angular 色获取导航项列表,将它们全部存储在对象列表中并将其序列化为 JSON 以返回到 Angular 。

我的方法目前运行良好,但数据到达页面至少需要 5 秒,而我的页面加载时间不到一秒。所以我的用户只是坐在那里等待导航项弹出,这不是很好。

以下是我使用的两种方法:

public NavDirectoryViewModel GetAllUserNavItems(string UserId)
{
NavDirectoryViewModel model = new NavDirectoryViewModel();
model.NavItems = new List<NavViewModel>();
foreach (var nav in GetAllNavItems())
{
if (GetUserNavItem(UserId, nav) != null)
{
if (nav.ParentId == 0)
model.NavItems.Add(GetUserNavItem(UserId, nav));
}
}
model.NavItems = model.NavItems.OrderBy(x => x.SortOrder).ToList();
return model;
}

public NavViewModel GetUserNavItem(string UserId, NavModel model)
{

try
{
if(model.AllowedUsers.FirstOrDefault(x => x.UserId.Equals(UserId)) != null || model.AllowedRoles.FirstOrDefault(x => x.Role.Users.FirstOrDefault(y => y.UserId.Equals(UserId)) != null) != null)
{
return new NavViewModel { Name = model.Name, Href = model.Href, Image = model.Image, SortOrder = model.SortOrder, SubItems = GetNavItems(model.Id).Where(x => x.ParentId == model.Id).Select(x => GetUserNavItem(UserId, x)).ToList() };
}
else
{
return null;
}
}
catch(Exception e1) { return null; }
}

这是两个模型:

public class NavViewModel
{
public string Name { get; set; }
public string Href { get; set; }
public string Image { get; set; }
public int? SortOrder { get; set; }

public List<NavViewModel> SubItems { get; set; }
}

public class NavModel
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public string Href { get; set; }
public string Image { get; set; }//string of server image path or fa class
public int ParentId { get; set; }//Will be 0 if it has no parent
public int? SortOrder { get; set; }


public virtual List<NavModel> SubItems { get; set; }
public virtual List<RoleNavAuthorizationModel> AllowedRoles { get; set; }
public virtual List<UserNavAuthorizationModel> AllowedUsers { get; set; }
}

Role 和 UserNavAuthorizationModels 仅存储 NavItem Id 和允许查看导航项的 Role/UserId。

最初我正在序列化 NavModel,这需要 10 到 15 秒,所以我制作了一个 View 模型,它没有存储那么多数据并且稍微加快了速度。但是,当其他所有内容都已加载时,我不能让我的用户等待导航栏加载。

调试的时候发现是GetUserNavItem需要一段时间的方法。其他一切都运行得非常快。

有人对如何加快速度有什么建议吗?

更新

这是 GetAllNavItems() 的代码:

public List<NavModel> GetAllNavItems() { return db.NavItems.ToList(); }

更新

我接受了 Ondrej Svejdar 关于缓存的建议,现在将 JSON 存储在用户的 session 中,这样如果在他们的 session 处于事件状态时重新加载页面,则完全不需要时间来重新加载。我把它放在我的 Controller 中:

if (HttpContext.Cache[User.Identity.GetUserId() + "NAV"] == null)
{
string NavJSON = JsonConvert.SerializeObject(nrepo.GetAllUserNavItems(User.Identity.GetUserId()), Formatting.Indented, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
HttpContext.Cache[User.Identity.GetUserId() + "NAV"] = NavJSON;
return Json(NavJSON, JsonRequestBehavior.AllowGet);
}
else
{
string NavJSON = HttpContext.Cache[User.Identity.GetUserId() + "NAV"].ToString();
return Json(NavJSON, JsonRequestBehavior.AllowGet);
}

最佳答案

那么,您应该重新考虑您的模型。您将安全问题与实际 [导航数据] 混为一谈,这就是为什么您被迫提供如此多的信息来验证用户身份的原因。

话虽这么说,但您有很多链式 LINQ 查询,如果您深入了解这些查询,可能会导致执行大量 SQL。试试这个:

public NavDirectoryViewModel GetAllUserNavItems(string userId)
{
NavDirectoryViewModel model = new NavDirectoryViewModel();
model.Items = GetNavItems(0, userId).OrderBy(x => x.SortOrder);
return model;
}

private static IEnumerable<NavViewModel> GetNavItems(int parentId, string userId)
{
List<NavViewModel> items = new List<NavViewModel>();
var children = GetAllNavItems(parentId);
foreach (var child in children)
{
if (child.IsUserAllowed(userId))
{
var navItem = new NavViewModel() { Name = child.Name, Href = child.Href, Image = child.Image, SortOrder = child.SortOrder };
navItem.SubItems = GetNavItems(child.Id, userId);
items.Add(navItem);
}
}
return items;
}

您将需要修改您的 GetAllNavItems,以便它只提取您在特定阶段需要的导航项。例如,顶级菜单 (ParentId = 0)。然后,您可以只使用递归方法来填充所有内容。

您还需要向 NavModel 类添加一个方法:

public bool IsUserAllowed(string userId)
{
return AllowedUsers.Any(x => x.UserId.Equals(userId)) || AllowedRoles.SelectMany(r => r.Role.Users).Any(y => y.UserId.Equals(userId));
}

注意在 LINQ 查询中使用 Any 与 FirstOrDefault。

这种修改应该会给您带来不错的速度,因为您不会提取不需要的数据,而且您会避免所有嵌套查询。您还在很多地方调用了 ToList(),这会导致执行查询并将数据投影到对象中。

不过,恕我直言,您的模型需要重新设计。提取的数据太多了。

我在几分钟内完成了这个,所以检查错误/语义,但这应该让您对如何提高性能有一个很好的了解。

关于c# - ASP .NET 获取数据太慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40425073/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com