【问题标题】:How to retrieve data from multiple tables and display in a view using viewmodel如何使用视图模型从多个表中检索数据并显示在视图中
【发布时间】:2015-04-06 14:29:30
【问题描述】:

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

事件

身份证

创建者

开始时间

是共享的

预算

事件用户

事件ID

用户ID

已接受

事件对象

事件ID

对象ID

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

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

/* linq expressions */

        return View();
    }
}
}

当参数传入时,我想;

*从 UID=UserID 的 EventUser 表中选择,并使用 EventID 属性将结果与 Event 和 EventObject 表连接。

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

我是 mvc 和 viewmodel 概念的新手。我听说 viewmodel 概念可以帮助解决这些情况。我可以通过使用 viewmodel 概念来克服这个问题。如果是,我需要在视图模型中添加什么?否则还有什么其他方法可以做到这一点?

【问题讨论】:

  • 您使用什么进行数据访问? Entityframework 还是普通的 ado.net?您可以通过实体框架连接来做到这一点。
  • 我正在使用Entityframework...我该怎么做??

标签: c# asp.net-mvc model-view-controller viewmodel


【解决方案1】:

我可以看到这样做的一种方法是创建一个自定义返回对象并使用 EF 将所有表连接在一起。示例

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 等替换为所需的相应表名。那么你需要做的就是

return View(results);

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

【讨论】:

    【解决方案2】:

    如果您的问题是关于使用诸如实体框架之类的 ORM 进行查询,您需要发布您的 entities,而不是您的表架构。 ORM 的全部目的是抽象出底层数据库结构,因此虽然模式通常与实体类相似,但也可能完全不同。因此,我将不得不对您的实体类做出假设。

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

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

    假设实体类如下:

    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。如果您需要访问单个事件的EventObjects,则必须使用适当的集合属性。例如:

    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; }
    }
    

    但是,使用该方法,无法根据是否接受来过滤包含的Events。有一种潜在的解决方法,但它需要完全禁用 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)直接传递到您的视图。

    【讨论】:

    • 是的,你的假设是基于我的代码..我尝试了以下代码......它有效;但我无法让所有其他还邀请参加该特定活动的用户进入视图。如何将用户 ID 列表获取到 veiwmodel?例如:如果参数 UserId 为 2 并且用户被邀请到 EventId 1 和 2,我想在视图中显示谁是事件 id 1 和事件 id 2 的其他用户。
    • public ActionResult Index(int UId) { var result1 = from eu in db.EventUsers where eu.UserId == UId select eu; var result2 = from eu1 in result1 join e in db.Events on eu1.EventId equals e.Id select new MessageViewModel { EventID1 = e.Id, IsAccepted= eu1.IsAccepted, CreatedBy = e.CreatedBy, Budget = e.Budget, }; return View(result2); }
    【解决方案3】:

    关于如何使用实体框架解决方案的高级描述如下:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-10
      • 2017-07-31
      • 2018-08-06
      相关资源
      最近更新 更多