在ASP.NET MVC Entitiy Framework的内容页中加载多组数据

在ASP.NET MVC Entitiy Framework的内容页中加载多组数据,asp.net,asp.net-mvc,entity-framework,Asp.net,Asp.net Mvc,Entity Framework,我需要在我的视图页面中加载多个实体类型。为此,我正在使用ViewModel。但是,我需要进行大约5-6次数据库调用来加载每组数据,并将它们分配给ViewModel的相关属性。我想知道这是否是一种推荐的方法,因为它需要多个数据库调用。或者,我是不是太担心这个了?以下是我的代码中的快照: var model = new EntryListVM(); string userid = ""; if (ViewBag.CurrentUserId == null)

我需要在我的视图页面中加载多个实体类型。为此,我正在使用
ViewModel
。但是,我需要进行大约5-6次数据库调用来加载每组数据,并将它们分配给
ViewModel
的相关属性。我想知道这是否是一种推荐的方法,因为它需要多个数据库调用。或者,我是不是太担心这个了?以下是我的代码中的快照:

    var model = new EntryListVM();

    string userid = "";
    if (ViewBag.CurrentUserId == null)
        userid = User.Identity.GetUserId();
    else
        userid = ViewBag.CurrentUserId;

    ViewBag.CurrentUserId = userid;

    //First database call
    model.DiscussionWall = db.DiscussionWalls.Find(wallId);

    //Second database call to learn if the current students has any entry
    model.DiscussionWall.DoesStudentHasEntry = db.Entries.Any(ent => ent.DiscussionWallId == wallId && ent.UserId == userid);
    model.PageIndex = pageIndex;

    //Third database call
    model.TeacherBadges = db.Badges.Where(b => b.CourseId == model.DiscussionWall.CourseId && b.IsSystemBadge == false && b.IsEnabled == true).ToList();

    //Fourth database call
    model.Reactions = db.Reactions.Where(re => re.CourseId == model.DiscussionWall.CourseId).ToList();

    int entryPageSize = Convert.ToInt32(ConfigurationManager.AppSettings["EntryPageSize"]);
    int firstChildSize = Convert.ToInt32(ConfigurationManager.AppSettings["FirstChildSize"]);

    List<ViewEntryRecord> entryviews = new List<ViewEntryRecord>();
    bool constrainedToGroup = false;
    if (!User.IsInRole("Instructor") && model.DiscussionWall.ConstrainedToGroups)
    {
        constrainedToGroup = true;
    }

    //Fifth database call USING VIEWS
    //I used views here because of paginating also to bring the first 
    //two descendants of every entry 
    entryviews = db.Database.SqlQuery<ViewEntryRecord>("DECLARE @return_value int;EXEC  @return_value = [dbo].[FetchMainEntries] @PageIndex = {0}, @PageSize = {1}, @DiscussionWallId = {2}, @ChildSize={3}, @UserId={4}, @ConstrainedToGroup={5};SELECT  'Return Value' = @return_value;", pageIndex, entryPageSize, wallId, firstChildSize, userid, constrainedToGroup).ToList();

    model.Entries = new List<Entry>();
    //THIS FUNCTION MAP entryviews to POCO classes
    model.Entries = ControllerUtility.ConvertQueryResultsToEntryList(entryviews);

    //Sixth database call
    var user = db.Users.Single(u => u.Id == userid);

    model.User = user;
var model=newentrylistVM();
字符串userid=“”;
如果(ViewBag.CurrentUserId==null)
userid=User.Identity.GetUserId();
其他的
userid=ViewBag.CurrentUserId;
ViewBag.CurrentUserId=用户ID;
//第一次数据库调用
model.DiscussionWall=db.DiscussionWalls.Find(wallId);
//第二次数据库调用以了解当前学生是否有任何条目
model.DiscussionWall.DoesStudentHasEntry=db.Entries.Any(ent=>ent.DiscussionWallId==wallId&&ent.UserId==UserId);
model.PageIndex=PageIndex;
//第三次数据库调用
model.TeacherBadges=db.Badges.Where(b=>b.CourseId==model.DiscussionWall.CourseId&&b.IsSystemBadge==false&&b.IsEnabled==true)。ToList();
//第四次数据库调用
model.Reactions=db.Reactions.Where(re=>re.CourseId==model.DiscussionWall.CourseId.ToList();
int entryPageSize=Convert.ToInt32(ConfigurationManager.AppSettings[“entryPageSize”]);
int firstChildSize=Convert.ToInt32(ConfigurationManager.AppSettings[“firstChildSize”]);
列表入口视图=新列表();
bool constrainedToGroup=false;
if(!User.IsInRole(“讲师”)&&model.DiscussionWall.ConstrainedToGroups)
{
constrainedToGroup=true;
}
//使用视图调用第五个数据库
//我在这里使用视图是因为分页也带来了第一个
//每个条目的两个后代
entryviews=db.Database.SqlQuery(“DECLARE@return_value int;EXEC@return_value=[dbo].[fetchmain条目]@PageIndex={0}、@PageSize={1}、@DiscussionWallId={2}、@ChildSize={3}、@UserId={4}、@ConstrainedToGroup={5};选择“return value'=@return value;”、PageIndex、entryPageSize、wallId、firstChildSize、UserId、ConstrainedToGroup”).ToList();
model.Entries=新列表();
//此函数将EntryView映射到POCO类
model.Entries=ControllerUtility.ConvertQueryResultsToEntryList(EntryView);
//第六次数据库调用
var user=db.Users.Single(u=>u.Id==userid);
model.User=User;
我想知道这对于初始页面加载来说是否是一个太大的负担

我可以使用SQL视图一次读取所有数据,但我想我会得到一个太复杂的数据集,无法管理

另一种选择是在页面加载(包含主数据)完成后使用Ajax加载附加结果。例如,我可以在加载页面后使用AJAX加载
TeacherBadges

我想知道哪种策略更有效,更值得推荐?是否存在特定情况下某一特定策略可能更有用的情况

谢谢

包括链接数据 对于链接数据,它很简单(您可能知道这种方式):

它查询所有用户并预加载每个用户的设置


对不同的数据集使用匿名类 以下是一个例子:

context.Users.Select(user => new 
{
    User = user,
    Settings = context.Settings
        .Where(setting => setting.UserId == user.Id)
        .ToList()
}).ToList();
您仍然需要选择主查询集合(本例中为用户),但这是一个选项。希望有帮助。

包括链接数据 对于链接数据,它很简单(您可能知道这种方式):

它查询所有用户并预加载每个用户的设置


对不同的数据集使用匿名类 以下是一个例子:

context.Users.Select(user => new 
{
    User = user,
    Settings = context.Settings
        .Where(setting => setting.UserId == user.Id)
        .ToList()
}).ToList();

您仍然需要选择主查询集合(本例中为用户),但这是一个选项。希望能有所帮助。

这取决于您的场景-不同的场景有不同的做事方式。没有一种正确的方法可以做本质上相似的事情。对我有用的东西可能对你无效。有没有听过这样一句话:
有很多方法可以杀死一只猫
?这当然适用于编程

我将根据我认为你在问的问题来回答。你的问题很广泛,没有那么具体

然而,我不确定这是否是一个推荐的方法,因为它 需要多个数据库调用

有时需要执行一个数据库调用来获取数据,有时需要执行多个数据库调用来获取数据。例如:

  • 带地址的用户详细信息:一次呼叫用户,一次呼叫地址
  • 用户详细信息:一次呼叫
为此,我使用ViewModel

在视图中使用
视图模型
是一件好事。如果你想阅读更多关于视图模型的内容,那么你可以去阅读我就这个主题给出的答案:

视图模型非常适合于具有来自多个数据集的数据的情况。视图模型还可用于显示来自一个数据集的数据,例如:

  • 显示具有多个地址的用户详细信息
  • 仅显示用户详细信息
我在单独的linq语句中读取控制器中的数据,然后 将它们指定给ViewModel的相关列表属性

我不会总是返回一个列表——这完全取决于你需要什么

如果要返回单个对象,则将填充单个对象:

User user = userRepository.GetById(userId);
如果我有一个要返回的对象列表,那么我将返回一个对象列表:

List<User> users = userRepository.GetAll();
你的观点可能是这样的:

@model List<YourProject.Models.User>

@if (Model.Count > 0)
{
     foreach (var user in Model)
     {
          <div>@user.Name</div>
     }
}
public class UserViewModel
{
     public UserViewModel()
     {
          Addresses = new List<Address>();
     }

     public int Id { get; set; }

     public string Name { get; set; }

     public List<Address> Addresses { get; set; }
}
public ActionResult Details(int id)
{
     User user = userRepository.GetById(id);
     UserViewModel model = new UserViewModel();
     model.Name = user.Name;
     model.Addresses = addressRepository.GetByUserId(id);

     return View(model);
}
然后,您需要在视图中显示用户详细信息和地址:

@model YourProject.ViewModels.UserViewModel

<div>First Name: @Model.Name</div>
<div>
     @if (Model.Addresses.Count > 0)
     {
          foreach (var address in Model.Address)
          {
               <div>@address.Line1</div>
               <div>@address.Line2</div>
               <div>@address.Line3</div>
               <div>@address.PostalCode</div>
          }
     }
</div>
@model YourProject.ViewModels.UserViewModel
名字:@Model.Name
@如果(Model.Addresses.Count>0)
{
foreach(Model.address中的变量地址)
{
@地址.第1行
@地址.第2行
@地址3.Line
@地址.邮政编码
}
}
public ActionResult Details(int id)
{
     User user = userRepository.GetById(id);
     UserViewModel model = new UserViewModel();
     model.Name = user.Name;
     model.Addresses = addressRepository.GetByUserId(id);

     return View(model);
}
@model YourProject.ViewModels.UserViewModel

<div>First Name: @Model.Name</div>
<div>
     @if (Model.Addresses.Count > 0)
     {
          foreach (var address in Model.Address)
          {
               <div>@address.Line1</div>
               <div>@address.Line2</div>
               <div>@address.Line3</div>
               <div>@address.PostalCode</div>
          }
     }
</div>