我正在尝试使用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概念克服了这个问题。是的,我需要在视图模型中添加什么?否则,其他方法是什么?
答案 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
对象,那么您最好首先查询该对象并包括相关的Event
和EventObject
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技术。)