Asp.net mvc 理解实体框架中的虚拟属性和计算属性

Asp.net mvc 理解实体框架中的虚拟属性和计算属性,asp.net-mvc,entity-framework,linq,Asp.net Mvc,Entity Framework,Linq,我有一个包含许多属性的作业模型和一组称为引号的链接实体: public class Job { .... public virtual ICollection<Quote> Quotes { get; set; } } 我有两个问题: 调试此属性时,Quotes为null(即使此实体附加了引号)。我认为使用virtual意味着这不应该发生?如何确保无论何时构建模型,都会附加相关的报价实体 我这样做的原因是属性值存储在数据库中,因此它减少了预先计算的计算时间,对吗 后

我有一个包含许多属性的作业模型和一组称为引号的链接实体:

public class Job
{
    ....
    public virtual ICollection<Quote> Quotes { get; set; }
}
我有两个问题:

  • 调试此属性时,
    Quotes
    为null(即使此实体附加了引号)。我认为使用
    virtual
    意味着这不应该发生?如何确保无论何时构建模型,都会附加相关的报价实体

  • 我这样做的原因是属性值存储在数据库中,因此它减少了预先计算的计算时间,对吗

  • 后续行动:

    在大多数情况下,我在检索作业对象时没有使用
    Include
    。我仅在需要
    QuotesAwarded
    值时才使用Include


    但是,如果我不使用
    Include
    (比如
    db.jobs.find(id)
    ),并且引号为空,那么
    引号向前的值将为0。因此,当我保存作业对象时,这将被保存到数据库中,我在这里真的把自己弄糊涂了。

    对于您的第一个问题,
    virtual
    关键字被用作指示实体框架延迟加载它。但是,您似乎已禁用延迟加载,因此始终需要
    。包括(…)
    它。由于您的属性依赖于加载的引号,因此它将始终返回0

    您所做的几乎是正确的,您只需要让EntityFramework知道您的属性是一个计算列。为此,只需使用属性对其进行注释:

    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public string QuotesAwarded
    {
        get
        {
            if (Quotes == null || !Quotes.Any())
            {
                return 0;
            }
    
            var totalUnapprovedQuotes = Quotes.Where(x => x.Status != "Approved");
    
            return 1 - (totalUnapprovedQuotes.Count() / Quotes.Count());
        }
    
        private set
        {
            //Make this private so there's no temptation to set it
        }
    }
    

    您使用的是惰性加载还是快速加载?你是如何从数据库中读取实体的?谢谢你的回答,我已经更新了问题谢谢这个@DavidG。我如何知道是否禁用了延迟加载?另外,让EF知道它是计算列有什么好处?
    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public string QuotesAwarded
    {
        get
        {
            if (Quotes == null || !Quotes.Any())
            {
                return 0;
            }
    
            var totalUnapprovedQuotes = Quotes.Where(x => x.Status != "Approved");
    
            return 1 - (totalUnapprovedQuotes.Count() / Quotes.Count());
        }
    
        private set
        {
            //Make this private so there's no temptation to set it
        }
    }