2016-07-25 82 views
3

我有一个工作模型,包含了许多特性,和一组链接的实体称为行情:了解虚拟化和计算性能

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

在我的作业类,我有以下计算性能:

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 
    { 

    } 

} 

我有2个问题:

  1. 当我调试此属性,Quotes为空(即使有附引号这个实体)。我认为,使用virtual意味着,这不应该发生的呢?我怎样才能确保在模型构建时,相关的报价实体被附加?

  2. 我这样做的原因是,该属性值存储在数据库中,所以它减少计算时间,因为它是预先计算的,这是正确的?检索作业对象时,我没有使用Include<Quotes>

    在大多数情况下:

跟进。我仅在需要QuotesAwarded值时才使用“包含”。

但是,如果我不使用Include(比如db.jobs.find(id)),和报价为空,而QuotesAwarded值将为0。所以,当我保存作业对象,这将得到保存到数据库中,我真的很迷茫我在这里。

+0

您是使用懒惰还是渴望加载?你如何从数据库中读取实体? – DavidG

+0

感谢您的答复,我已经更新了问题 –

回答

2

为了您的第一个问题,virtual关键字被用作指示实体框架懒洋洋地加载此。然而,似乎已禁用延迟加载,所以你总是需要.Include(...)它。由于您的财产依赖于正在加载的报价,因此它将始终返回0.

您所做的事情几乎是正确的,您只需让Entity Framework知道您的属性是计算列。要做到这一点,您只需要使用属性对其进行注释:

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

感谢这个@DavidG。我如何知道延迟加载是否被禁用?还有什么让EF知道它是一个计算列的好处? –