1

我正在 Visual Studio 中学习 MVC4,对此我有很多疑问。我对 MVC 的第一个声明是 MVC 的模型没有达到我的预期。我希望模型根据需要选择并返回数据行。

但是我阅读了很多教程,他们建议我让模型从表中返回所有数据,然后消除控制器中不需要的数据,然后将其发送到视图。

这是教程中的代码

模型

public class ApartmentContext : DbContext
{
    public ApartmentContext() : base("name=ApartmentContext") { }
    public DbSet<Apartment> Apartments {    get; set;   }
}

控制器

 public ActionResult Index()
    {
        ApartmentContext db = new ApartmentContext();
        var apartments = db.Apartments.Where(a => a.no_of_rooms == 5);
        return View(apartments);
    }

这是将“where 子句”应用于选择语句的正确方法吗?我不想选择所有数据然后消除不需要的行。这对我来说似乎很奇怪,但每个人都建议这样做,至少我阅读的教程建议这样做。

4

3 回答 3

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 子句”应用于选择语句的正确方法吗?

是的,这种方式很好。但是,您需要了解当您WhereIQueryable<T>. 我假设您使用的是 EF,因此Where查询不会立即执行(因为 EF 使用延迟执行)。所以基本上你正在向你的视图传递一个尚未运行的查询,并且只有在视图尝试呈现数据的地方才是查询将运行的时间 - 到那时你ApartmentContext将被处置并因此抛出一个例外。

db.Apartments.Where(...).ToList();

这会导致查询立即执行,这意味着您的查询不再依赖于上下文。但是,在 MVC 中这样做仍然不是正确的做法,我提供的示例被认为是推荐的方法。

于 2013-05-30T09:36:06.980 回答
1

我看不到这些教程,但你确定它正在加载所有数据吗?看起来您使用实体框架和实体框架使用Lazy laoding。和延迟加载状态:

启用延迟加载后,通过导航属性访问相关对象时会加载相关对象。

因此,您似乎加载了所有数据,但数据本身仅在您访问对象本身时才从 SQL 中检索。

于 2013-05-30T09:46:37.940 回答
1

在我们的项目中,我们将添加一个数据访问层,而不是访问控制器中的域。并返回视图模型而不是域。

但是你的代码,你只选择你需要的数据而不是所有的数据。

如果您打开 SQL Profiler,您会看到这是一个带有 where 条件的 select 语句。

因此,如果这不是一个大项目,我认为没关系。

于 2013-05-30T09:39:11.247 回答