如何使用 viewmodel 从多个表中检索数据并显示在视图中

How to retrieve data from multiple tables and display in a view using viewmodel

我正在尝试使用 mvc 5 为我的 mvc 应用程序开发一个消息传递系统。我有 tables 称为 Event、EventUser、EventObject。每个 table 都有以下内容;

事件

编号

创建者

开始时间

共享

预算

事件用户

事件ID

用户ID

已接受

事件对象

事件ID

对象ID

在我的 messageController 中,我有接收用户参数的索引方法 id.i 需要显示用户使用此方法邀请的每个事件..

namespace MvcApp.Controllers
{
public class MessageController : Controller
{
    private EPlannerDatabaseEntities db = new EPlannerDatabaseEntities();
    // GET: /Message/
    public ActionResult Index(int UId)
    {

/* linq expressions */

        return View();
    }
}
}

参数传入后,我要;

*Select 来自 EventUser table,其中 UID=UserID 并使用 EventID 属性将结果与 Event 和 EventObject tables 连接。

*最后,通过使用最终结果,我需要显示用户邀请的每个事件的信息;像 CreatedBy , StartTime, Budget, other users, objects etc..

我是 mvc 和 viewmodel 的新手 concept.I 听说 viewmodel 概念可以帮助解决这些问题 situations.can 我通过使用 viewmodel 解决了这个问题 concept.if 是的,我需要什么在视图模型中添加??否则还有什么其他方法可以做到这一点?

我看到的一种方法是创建自定义 return 对象并使用 EF 将所有 table 连接在一起。示例

public class MyObject{
      public DateTime DateCreated{get;set}
     // add remaining properties here
     // properties to get back
}

然后在代码中,您将使用 Entity Framework 将连接的数据集创建到一个漂亮的对象列表中。示例:

    var results =  (from b in bla join bla2 in (Some Second Query Here)
                    from SomeSecondQueryHere
                    where cond1 and cond2 Select new MyObject{
                    // add properties in here}) 

您可以将 bla 和 bla2 等替换为所需的相应 table 名称。那么你需要做的就是

return View(results);

并且可以在视图中访问更改

如果您的问题是关于使用像 Entity Framework 这样的 ORM 进行查询,您需要 post 您的 实体 ,而不是您的 table 模式. ORM 的全部目的是抽象出底层数据库结构,因此虽然模式通常与实体 class 相似,但也可能完全不同。因此,我将不得不对您的实体做出假设 classes.

要查询所有内容,您只需要如下内容:

var events = db.Events.Where(m => 
    m.EventUsers.Any(u => u.UserID == UId && u.IsAccepted)
).Include(m => m.EventObjects);

假定实体 class 符合以下行:

public class Event
{
    ...

    public virtual ICollection<EventObject> EventObjects { get; set; }
    public virtual ICollection<EventUser> EventUsers { get; set; }
}

public class EventUser
{
    ...
    public int UserID { get; set; }
    public bool IsAccepted { get; set; }
}

你最终得到一个可枚举的 Event。如果您需要访问单个事件的 EventObject,则必须使用适当的集合 属性。例如:

foreach (var item in events)
{
    foreach (var obj in item.EventObjects)
    {
        // do something with `obj` (an invidual `EventObject` instance)
    }
}

如果您需要实际的 User 对象,您最好先查询对象并包括相关的 Events 和 EventObjects:

var user = db.Users.Include("EventUsers.Event.EventObjects").SingleOrDefault(m => m.UserID == UId);

假定实体如下:

public class User
{
    ...
    public virtual ICollection<EventUser> EventUsers { get; set; }
}

public class EventUser
{
    ...
    public virtual Event Event { get; set; }
}

public class Event
{
    ...
    public virtual ICollection<EventObject> EventObjects { get; set; }
}

但是,使用该方法无法根据是否接受来过滤包含的 Event。有一种潜在的解决方法,但它需要完全禁用 EventUsers 的延迟加载,并使查询所需信息变得复杂。如果您需要走那条路,请参阅:https://msdn.microsoft.com/en-us/data/jj574232.aspx#explicitFilter.

否则,您可以在迭代集合之前排除未接受的事件:

var events = user.EventUsers.Where(m => m.IsAccepted).Select(m => m.Event);

实际上,您不需要视图模型,就其本身而言,对于任何这些。因为您可以将事件列表(将包括任何相关的 EventObjects)或单个用户实例(包括相关事件和相关的 EventObjects)直接传递到您的视图。

关于如何使用 Entity Framework 解决您的场景的非常高级的描述如下:

首先,您必须创建一系列实体数据对象,这些对象将使用 EF 代码优先技术在 EF 数据模型中表示您的表。 然后,您使用 DbSets 为之前创建的实体创建 DbContext 对象。 然后,您至少创建一个服务 class,它将有一个 属性 表示 DbContext 和一组将 Linq 查询封装到您的实体的方法。 在 MVC 控制器中,您调用之前创建的服务实例并将其分配给 属性 蚂蚁控制器的构建时间。最后,在 Action 方法中,您应该调用正确的 Service 方法并将任何结果传递给视图。 (我假设这是一个带有少量表格的小型 Ad-Hoc 系统,一个具有生产质量的精心设计的系统将需要使用 IoC 技术)。