了解实体框架

时间:2016-07-25 23:29:18

标签: asp.net-mvc entity-framework linq

我有一个包含许多属性的Job模型,以及一组名为Quotes的链接实体:

public class Job
{
    ....
    public virtual ICollection<Quote> Quotes { get; set; }
}

在我的Job类中,我有以下计算属性:

public decimal QuotesAwarded
{
    get
    {
        if (Quotes == null || !Quotes.Any())
        {
            return 0;
        }

        var totalUnapprovedQuotes = Quotes.Where(x => x.Status != "Approved");

        return 1 - (totalUnapprovedQuotes.Count() / Quotes.Count());

    }
    set
    {

    }

}

我有两个问题:

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

  2. 我这样做的原因是属性值存储在数据库中,所以它减少了预先计算的计算时间,这是正确的吗?

    < / LI>

    跟进:

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

    但是,如果我不使用Include(例如db.jobs.find(id)),并且引号为空,则QuotesAwarded值将为0.这样就会保存到我保存工作对象时的数据库,我在这里真的很困惑。

1 个答案:

答案 0 :(得分:2)

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

您正在做的几乎是正确的,您只需要让实体框架知道您的属性是计算列。要做到这一点,您只需要使用属性注释它:

[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
    }
}