3

从查询中加载 ICollection<> 虚拟成员时,是否有任何方法可以确定何时将实际项目添加到该成员?

希望下面的代码能够证明我的观点!!

public class DbAppointment
{
    public DbAppointment()
    {
    }

    public virtual int AppointmentId { get; set; }
    public virtual string Subject { get; set; }
    public virtual string Body { get; set; }
    public virtual DateTime Start { get; set; }
    public virtual DateTime End { get; set; }

   private ICollection<DbExceptionOcurrence> exceptionOcurrences;
   public virtual ICollection<DbExceptionOcurrence> ExceptionOcurrences
   {
        get { return exceptionOcurrences; }
        set
        {
            exceptionOcurrences = value;
        }
    }
}

public class DbExceptionOcurrence
{
    public DbExceptionOcurrence()
    {
    }

    public virtual int ExceptionId { get; set; }
    public virtual int AppointmentId { get; set; }
    public virtual DateTime ExceptionDate { get; set; }
    public virtual DbAppointment DbAppointment { get; set; }
}

加载这些的代码是

        Database.SetInitializer(new ContextInitializer());
        var db = new Context("EFCodeFirst");

        // when this query executes the DbAppointment ExceptionOcurrenes (ICollection) is set
        // but for some reason I only see this as an empty collection in the virtual setter DbAppointment
        // once the query has completed I can see the ExceptionOcurrences
        var result = db.Appointments.Include(a => a.ExceptionOcurrences).ToList();

在每个项目的 DbAppointment ICollection ExceptionOcurrences 设置器中,我需要执行一些额外的逻辑。我遇到的问题是,一旦创建了 DbAppointment 对象,我似乎才拥有此信息。

有什么方法可以确定何时添加了这些项目,以便我可以执行我的逻辑。

干杯腹肌

4

1 回答 1

2

显然,您看到的行为意味着 Entity Framework 创建并填充与此类似的集合:

// setter called with empty collection
dbAppointment.ExceptionOcurrences = new HashSet<DbExceptionOcurrence>();

// only getter gets called now
dbAppointment.ExceptionOcurrences.Add(dbExceptionOcurrence1);
dbAppointment.ExceptionOcurrences.Add(dbExceptionOcurrence2);
dbAppointment.ExceptionOcurrences.Add(dbExceptionOcurrence3);
//...

我曾希望您可以使用ObjectMaterialized 事件(可以DbContext在此示例中注册:https : //stackoverflow.com/a/4765989/270591,EventArgs 包含物化实体)但不幸的是文档说:

在对象上设置了所有标量、复杂和引用属性之后,但在加载集合之前引发此事件。

看起来您必须在完全加载结果集合后运行它,并在每个结果项上调用一些方法,该方法在导航集合上执行您的自定义逻辑。

也许另一种选择是创建一个自定义集合类型,该集合类型ICollection<T>使用该方法的事件处理程序实现,Add并允许您在每次添加新项目时挂钩某些逻辑。您在模型类中的导航集合必须属于该类型。也许甚至ObservableCollection<T>可以用于此目的。

于 2012-06-16T12:35:21.667 回答