我在Visual Studio中学习MVC4,我对此有很多疑问。我关于MVC的第一个声明是MVC的模型没有达到我的预期。我希望Model能够根据需要选择并返回数据行。
但是我阅读了很多教程,他们建议我让模型从表中返回所有数据,然后在控制器中删除我不需要的数据,然后将其发送到View。
这是教程中的代码
MODEL
public class ApartmentContext : DbContext
{
public ApartmentContext() : base("name=ApartmentContext") { }
public DbSet<Apartment> Apartments { get; set; }
}
CONTROLLER
public ActionResult Index()
{
ApartmentContext db = new ApartmentContext();
var apartments = db.Apartments.Where(a => a.no_of_rooms == 5);
return View(apartments);
}
这是将“where子句”应用于select语句的正确方法吗?我不想选择所有数据,然后消除不需要的行。这对我来说似乎很奇怪,但每个人都建议这样,至少我读到的教程建议这样做。
答案 0 :(得分:4)
你读过的教程是错误的(在我看来)。您不应该将实际实体返回到您的视图,您应该返回查看模型。以下是我重写你的例子的方法:
public class ApartmentViewModel
{
public int RoomCount { get; set; }
...
}
public ActionResult Index()
{
using (var db = new ApartmentContext())
{
var apartments = from a in db.Apartments
where a.no_of_rooms == 5
select new ApartmentViewModel()
{
RoomCount = a.no_of_rooms
...
};
return View(apartments.ToList());
}
}
这是将“where子句”应用于select语句的正确方法吗?
是的,这种方式很好。但是,当您在Where
上调用IQueryable<T>
(和各种其他LINQ命令)时,您需要了解实际发生的情况。我假设您正在使用EF,因此Where
查询不会立即执行(因为EF使用延迟执行)。因此,基本上您将视图传递给尚未运行的查询,并且仅在视图尝试呈现数据的位置时查询将运行 - 此时您的ApartmentContext
将被处理并且结果抛出异常。
db.Apartments.Where(...).ToList();
这会导致查询立即执行,这意味着您的查询不再依赖于上下文。但是,在MVC中它仍然不是正确的做法,我提供的示例被认为是推荐的方法。
答案 1 :(得分:1)
在我们的项目中,我们将添加数据访问层而不是访问控制器中的域。并返回视图模型而不是Domain。
但是您的代码,您只需选择您需要的数据而不是所有数据。
如果您打开SQL事件探查器,您将看到这是一个带有where条件的select语句。
所以,如果它不是一个大项目,我认为没关系。
答案 2 :(得分:1)
我无法看到这些教程,但您确定它会加载所有数据吗?看起来您的使用实体框架和实体框架使用Lazy laoding。和懒惰加载状态:
启用延迟加载后,相关对象会在加载时加载 通过导航属性访问。
因此,您可能会加载所有数据,但只有在访问对象本身时才会从SQL中检索数据本身。