【问题标题】:MVC 'public virtual Collection...'MVC '公共虚拟集合...'
【发布时间】:2013-12-29 00:41:29
【问题描述】:

我是 MVC 的新手。任何人都可以解释以下拍卖类中第 8 到 13 行的元素:

public class Auction
{
    public int lngAuctionId { get; set; }
    public string txtTitle { get; set; }

    public virtual Collection<Bid> Bids { get; private set; }

    public Auction()
    {
        Bids = new Collection<Bid>();
    }
}

【问题讨论】:

  • 这不是 MVC 特有的。但无论如何,virtual 关键字允许任何从 Auction 派生的类都可以覆盖该属性并以他们想要的任何方式使用它。构造函数初始化并实例化 Bids 集合。默认情况下,您只能从类外部获取属性但不能设置它 - 您只能在类中设置它,就像它目前正在做的那样
  • 您可能想知道 Entity Framework 的延迟加载,它要求属性是虚拟的。你的实际问题是什么,是什么让你问 this 问题?

标签: c# .net collections virtual


【解决方案1】:

我相信这个类是由您的 ORM(如实体框架)存储在数据库中的。使属性虚拟化允许 ORM 在继承的类中覆盖此属性。为什么 ORM 需要它?允许延迟加载或存储在其他表中的实体。

它是如何工作的。您想将拍卖和出价存储在数据库中。关系很简单 - 拍卖可以有多个出价(即数据库中的出价将具有用于拍卖的外键)。

当您从数据库加载拍卖时,如果启用了延迟加载,则不会加载出价,这是默认设置(否则它可以下载整个数据库数据以进行单个查询)。 ORM 返回从拍卖继承的对象。是的,它们仍然是拍卖,但类型不同:

public class DbAuction : Auction
{    
    private DbContext _context;

    public DbAuction(DbContext context)
    {           
        Bids = new Collection<Bid>();
        _context = context;
    }

    public override Collection<Bid> Bids 
    {
        get 
        { 
            // here ORM checks whether this auction has bids loaded
            // and if it hasn't then ORM makes database query
            // and downloads related bids
        } 
        private set { /* ... */ }
    }
}

因此,属性标记为 virtual 以允许添加一些功能以在派生类中获取或设置其值。当您尝试获取属性值时,ORM 使用此功能添加从数据库加载其他数据的功能。

 // this code will return auction of some specific derived type
 // and ORM will load data only from Auctions table
 var auction = context.Auctions.Find(id);
 // and only here due to overridden virtual property
 // ORM will make another call to database and get data from Bids table
 var bids = auction.Bids;

【讨论】:

    【解决方案2】:

    该类具有不应从外部设置的集合属性(因此private set 和c'tor 中的内部一次性初始化)。只能操作集合值。

    但没有明显的理由将其标记为virtual

    【讨论】:

      【解决方案3】:

      第 10-13 行是构造函数。所以当你执行Auction variablename = new Auction();时,第12行的代码将被执行。

      第 8 行声明了一个名为 Bids 的公共属性,它使用通用的 Collection&lt;T&gt;,其中 T 是一个 Bid。 (Google .NET 泛型了解更多信息。)“虚拟”表示该属性可以被子类覆盖。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-22
        相关资源
        最近更新 更多