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

时间:2015-04-06 14:29:31

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

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

事件

ID

CreatedBy

开始时间

IsShared

预算

EventUser

事件ID

用户ID

IsAccepted

的EventObject

事件ID

的ObjectID

在我的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();
    }
}
}

参数传入后,我想;

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

*最后通过使用最终结果,我需要显示用户邀请的每个事件的信息;像CreatedBy,StartTime,Budget,其他用户,对象等。

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

3 个答案:

答案 0 :(得分: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);

可以在视图

中访问更改

答案 1 :(得分:0)

如果您对使用ORM(如Entity Framework)进行查询提出疑问,则需要发布实体,而不是您的表模式。 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的可数。如果您需要访问单个事件的EventObject,则必须使用相应的集合属性。例如:

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

如果您需要实际的User对象,那么您最好首先查询该对象并包括相关的EventEventObject s:

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

对于任何这种情况,你真的不需要视图模型。您可以将事件列表(包括任何相关的EventObject)或单个用户实例(包括相关事件和相关EventObject)直接传递给您的视图。

答案 2 :(得分:0)

如何使用Entity Framework解决您的场景的高级描述将是这样的:

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