虚拟关键字,包括扩展方法,延迟加载,渴望装载 - 如何加载相关对象的实际工作 [英] virtual keyword, Include extension method, lazy loading, eager loading - how does loading related objects actually work

查看:126
本文介绍了虚拟关键字,包括扩展方法,延迟加载,渴望装载 - 如何加载相关对象的实际工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在MVC加载相关的对象可以是pretty混乱。

有很多方面的,你需要知道并了解,如果你真的想知道你写你的实体模型类和控制器的时候在做​​什么。

这是我已经有很长一段时间的几个问题是:如何在虚拟关键字的工作时,我应该使用它?以及如何做的包含扩展方法的工作,当我应该使用它?

下面就是我说的;

虚拟关键字:

 使用系统;
使用System.Collections.Generic;
使用System.Linq的;
使用的System.Web;命名空间LazyLoading.Models
{
    公共类品牌
    {
        公众诠释BrandId {搞定;组; }
        公共字符串名称{;组; }
        公众诠释ManufacturerId {搞定;组; }
        公共虚拟制造商制造商{搞定;组; }
    }
}

以及包含扩展方法:

 使用系统;
使用System.Collections.Generic;
使用System.Data这;
使用System.Data.Entity的;
使用System.Linq的;
使用的System.Web;
使用System.Web.Mvc;
使用LazyLoading.Models;命名空间LazyLoading.Controllers
{
    公共类LazyLoadingStoreController:控制器
    {
        私人UsersContext DB =新UsersContext();        //
        // GET:/ LazyLoadingStore /        公众的ActionResult指数()
        {
            VAR品牌= db.Brands.Include(B = GT; b.Manufacturer);
            返回查看(brands.ToList());
        }        ...其他的操作方法...

请注意,指数()操作方法是由Visual Studio自动生成。是的,Visual Studio中自动添加 .INCLUDE(B = GT; b.Manufacturer)。这是pretty不错。


解决方案

我创建了一个测试MVC4互联网应用。

下面是我发现的:

首先,创建实体模型类 - 请注意为制造商虚拟关键字属性:

 公共类制造商
{
    公众诠释ManufacturerId {搞定;组; }
    公共字符串名称{;组; }
    公众的ICollection<品牌>品牌{搞定;组; }
}公共类品牌
{
    公众诠释BrandId {搞定;组; }
    公共字符串名称{;组; }
    公众诠释ManufacturerId {搞定;组; }
    公共虚拟制造商制造商{搞定;组; }
}

接下来,创建你的控制器 - 我创建(使用自动生成创造新的控制器对话框)与CRUD操作方法和视图我的。注意包含这是Visual Studio的感谢自动自动生成到您品牌模型类的关系扩展方法。

 公共类LazyLoadingStoreController:控制器
{
    私人UsersContext DB =新UsersContext();    //
    // GET:/ LazyLoadingStore /    公众的ActionResult指数()
    {
        VAR品牌= db.Brands.Include(B = GT; b.Manufacturer);
        返回查看(brands.ToList());
    }

让我们删除包含部分,现在让我们的操作方法是这样的:

 公众的ActionResult指数()
{
    VAR品牌= db.Brands;
    返回查看(brands.ToList());
}

和这是首页视图将如何看在页面检查器添加几个品牌对象后 - 公告该Visual Studio自动添加下拉的制造商,以及它如何自动脚手架为名称列制造商 - 甜!:

创建操作方法:

  //
// GET:/ LazyLoadingStore /创建公众的ActionResult的Create()
{
    ViewBag.ManufacturerId =新的SelectList(db.Manufacturers,ManufacturerId,姓名);
    返回查看();
}

真棒。一切都是自动生成的我们呢!

现在,如果我们要从我们的制造商虚拟关键字发生属性?

 公共类品牌
{
    公众诠释BrandId {搞定;组; }
    公共字符串名称{;组; }
    公众诠释ManufacturerId {搞定;组; }
    公共制造商制造商{搞定;组; }
}

这是会发生什么 - 我们的制造商的数据已经一去不复返了:

好吧,是有道理的。如果我重新添加包含扩展方法(用虚拟制造商仍然被删除属性)?

 公众的ActionResult指数()
{
    VAR品牌= db.Brands.Include(B = GT; b.Manufacturer);
    返回查看(brands.ToList());
}

这是从加回的结果包含扩展方法 - 在制造商数据又回来了:

这就是如何将所有的东西的工作。

接下来的事情是解释什么样的,获取在两种情况下的场景(延迟加载和预先加载)的后面产生的T-SQL的。我会留给别人。 :)

请注意:Visual Studio中自动生成包括(B = GT; b.Manufacturer) wheather您添加虚拟关键字或没有。

注2:哦,是的。差点忘了。这里有一些链接到一些不错的Microsoft资源。

有关性能方面的考虑第二个环节会谈而其他环节缺少如果是这样的东西,让你去。

Loading related object in MVC can be pretty confusing.

There are lots of terms you need to be aware of and learn if you really want to know what you're doing when writing your entity model classes and controllers.

A couple of questions that I've had for a very long time are: How does the virtual keyword work and when should I use it? And how does the Include extension method work and when should I use it?

Here's what I'm talking about;

virtual keyword:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace LazyLoading.Models
{
    public class Brand
    {
        public int BrandId { get; set; }
        public string Name { get; set; }
        public int ManufacturerId { get; set; }
        public virtual Manufacturer Manufacturer { get; set; }
    }
}

And the Include extension method:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using LazyLoading.Models;

namespace LazyLoading.Controllers
{
    public class LazyLoadingStoreController : Controller
    {
        private UsersContext db = new UsersContext();

        //
        // GET: /LazyLoadingStore/

        public ActionResult Index()
        {
            var brands = db.Brands.Include(b => b.Manufacturer);
            return View(brands.ToList());
        }

        ... Other action methods ...

Notice that the Index() action method is autogenerated by Visual Studio. Yes, Visual Studio automatically added the .Include(b => b.Manufacturer). That's pretty nice.

解决方案

I created a test MVC4 internet application.

Here's what I found:

First, create your entity model classes - notice the virtual keyword for the Manufacturer property:

public class Manufacturer
{
    public int ManufacturerId { get; set; }
    public string Name { get; set; }
    public ICollection<Brand> Brands { get; set; }
}

public class Brand
{
    public int BrandId { get; set; }
    public string Name { get; set; }
    public int ManufacturerId { get; set; }
    public virtual Manufacturer Manufacturer { get; set; }
}

Next, create your controller - I created (autogenerated using create new controller dialog) mine with CRUD action methods and views. Notice the Include extension method that was autogenerated automatically by Visual Studio thanks to the relationship in you Brand model class.

public class LazyLoadingStoreController : Controller
{
    private UsersContext db = new UsersContext();

    //
    // GET: /LazyLoadingStore/

    public ActionResult Index()
    {
        var brands = db.Brands.Include(b => b.Manufacturer);
        return View(brands.ToList());
    }

Let's remove the Include part for now so that our action method looks like this:

public ActionResult Index()
{
    var brands = db.Brands;
    return View(brands.ToList());
}

And this is how the Index view will look in Page Inspector after adding a couple of Brand objects - notice that Visual Studio automatically added the dropdown for Manufacturer and how it automatically scaffolded the Name column for Manufacturer - sweet!:

The Create action method:

//
// GET: /LazyLoadingStore/Create

public ActionResult Create()
{
    ViewBag.ManufacturerId = new SelectList(db.Manufacturers, "ManufacturerId", "Name");
    return View();
}

Awesome. Everything was autogenerated for us!

Now, what happens if we remove the virtual keyword from our Manufacturer property?

public class Brand
{
    public int BrandId { get; set; }
    public string Name { get; set; }
    public int ManufacturerId { get; set; }
    public Manufacturer Manufacturer { get; set; }
}

This is what will happen - our Manufacturer data is gone:

Okay, makes sense. What if I add back the Include extension method (with virtual still removed from the Manufacturer property)?

public ActionResult Index()
{
    var brands = db.Brands.Include(b => b.Manufacturer);
    return View(brands.ToList());
}

This is the result from adding back the Include extension method - The Manufacturer data is back!:

So that's how all that stuff work.

Next thing would be to explain what kind of T-SQL that gets generated behind the scenes in both cases (Lazy loading and Eager loading). That I'll leave to someone else. :)

Note: Visual Studio automatically generates Include(b => b.Manufacturer) wheather you add the virtual keyword or not.

Note2: Oh, yeah. Almost forgot. Here are some links to some good Microsoft resources.

The second link talks about performance considerations which the other link lacks if that is something that gets you going.

这篇关于虚拟关键字,包括扩展方法,延迟加载,渴望装载 - 如何加载相关对象的实际工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆