如何观察 DbSet<T> 的 Add 操作?

6

我有两个类,分别叫做ContactContactField。当ContactField被添加到Contact中时,我希望自动将SortOrder赋值给ContactField。我需要继承DbSet并自定义Add方法吗?如何实现?

public class Foo {
        private MyDbContext _db = new MyDbContext();

        public void HelloWorld() {
            Contact contact = ....; //< A contact from database.

            ContactField field = ....; ///< A new field 
            .... ///< assign other properties into this `field`
            field.FieldType = FieldType.Phone;

            // How to automatically update `SortOrder` 
            // when adding field into `ContactFields`
            contact.ContactFields.Add(field);

            _db.SaveChanges();
        }
}

public class Contact {
        public long ContactID { get; set; }

        public string DisplayName { get; set; }
        public string DisplayCompany { get; set; }
        public DateTime CreatedTime { get; set; }
        public DateTime ModifiedTime { get; set; }

        // Original codes    
        //public virtual ICollection<ContactField> ContactFields { get; set; }
        public virtual MyList<ContactField> ContactFields { get; set; }
}

 public class ContactField {
        public long ContactFieldID { get; set; }
        public int SortOrder { get; set; }
        public int FieldType { get; set; }

        public string Value { get; set; }
        public string Label { get; set; }

        [Column("ContactID")]
        public int ContactID { get; set; }
        public virtual Contact Contact { get; set; }
 }

编辑: 我发现我需要监控ICollection<ContactField> ContactFields的更改。而List<T>ICollection<T>的实现。因此,我创建了一个自定义的MyList并要求它通知MyList容器的更改。稍后我会测试它是否有效。

public class MyList<TEntity> : List<TEntity> {
        public delegate OnAddHandler(object sender, TEntity entry);
        public event OnAddHandler OnAddEvent;

        public new void Add(TEntity entity) {
             OnAddEvent(this, entity); 
             base.Add(entity);
        }
 }
2个回答

7

DbSet有一个属性叫做Local,它是一个ObservableCollection。您可以订阅CollectionChanged事件并在那里更新排序顺序。

public class Foo {
        private MyDbContext _db = new MyDbContext();

        public void HelloWorld() {

            _db.Contacts.Local.CollectionChanged += ContactsChanged;

            Contact contact = ....; //< A contact from database.

            ContactField field = ....; ///< A new field 
            .... ///< assign other properties into this `field`
            field.FieldType = FieldType.Phone;

            // How to automatically update `SortOrder` 
            // when adding field into `ContactFields`
            contact.ContactFields.Add(field);

            _db.SaveChanges();
        }

        public void ContactsChanged(object sender, NotifyCollectionChangedEventArgs args) {

            if (args.Action == NotifyCollectionChangedAction.Add)
            {

                // sort
            }    
        }
}

如果 Contact 尚未保存到 _db,我能观察 ICollection<ContactField> ContactFieldsAdd 操作吗? - AechoLiu
2
请记住,访问.Local会将整个表从数据库加载到内存中。即使是中等大小的表也会对性能产生巨大影响! - Breeze

1

或者覆盖 DbContext 上的 SaveChanges 方法,并使用本地 ChangeTracker 属性查找特定类型的新实体并设置其排序顺序属性。这对于在一个地方设置诸如最后更新日期之类的东西非常有效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接