【问题标题】:Entity framework custom inheritance with caliburn.micro使用 caliburn.micro 的实体框架自定义继承
【发布时间】:2017-07-05 13:02:36
【问题描述】:

我正在使用 caliburn.micro 编写一个 WPF 应用程序来处理数据库。我正在使用实体框架和数据库优先方法(因为我已经有一个数据库)来生成类。是否可以使实体框架生成将继承 caliburn 的 PropertyChangedBase 类的类,或者使它们实现 IHandle 接口。我需要这些类来让视图知道数据何时更改。

【问题讨论】:

  • 我建议您保留 EF POCO 模型(即“普通旧类对象”),并让视图模型实现 PropertyChangedBase,并管理模型是否“脏”和过时,或不等。
  • @Joe 的问题是,如果在您的视图模型中您有一个未实现 PropertyChanged 的​​类,并且该类的属性已更改,则不会对其进行更新。如果您仅在视图模型中实现 PropertyChanged,它只会在您更改整个类(新建或替换引用)时触发
  • 这就是为什么不可变模型更好!目前模型什么时候改变?当然,您最终会得到来自不同 EF dbContext 的不同模型实例(因此更改不会通过属性通知传播)?
  • @Joe 我的意思是如果你的虚拟机有一个类型为 Person 的属性(一个表)并且你绑定到 person.Name (所述表的一个列),并且你改变了属性(名称),viewmodel 不会触发 PropertyChanged 事件,因为它认为它的属性(即 Person 类)从未改变
  • 啊,我明白了。纯粹的 MVVM 方法是镜像 VM 中的属性。该模型具有属性名称。 VM 具有属性名称并实现通知。如果您想实现“保存/撤消”,这可能很有用。保存将属性应用于模型,撤消使用模型将它们恢复。维持起来更痛苦,但在做了这两件事之后,我确实喜欢这种分离。信息太多我会写一个答案(即使它不是专门针对问题的答案)。

标签: c# wpf entity-framework entity caliburn


【解决方案1】:

您可以在项目中编辑.tt 模板的副本:

Modifying Entity Framework Types T4 Template

使用此模板创建自动生成的实体类。

【讨论】:

    【解决方案2】:

    “纯粹”的 MVVM 方法(它不是一成不变的,许多人确实在他们的模型中实现了通知)将镜像您的视图模型中的属性。

    Person 为例,您的模型是一个简单的 POCO:

    public class Person
    {
        public String FirstName { get; set; }
        public String Surname { get; set; }
    }
    

    您的视图模型将其转换为要查看的内容,一个非常简单的版本可以使用“模型”作为它的支持字段:

    public class PersonViewModel : PropertyChangedBase
    {
        private Person person;
        public Person Person
        {
            get { return person; }
            set { person = value;
                  NotifyOfPropertyChange(() => FirstName);
                  NotifyOfPropertyChange(() => Surname)};
        }
    
        public String FirstName
        {
            get { return Person.FirstName; }
            set
            {
                if (Person.FirstName != value)
                {
                    Person.FirstName = value;
                    NotifyOfPropertyChange(() => FirstName);
                }
            }
        }
    
        public String Surname
        {
            get { return Person.Surname; }
            set
            {
                if (Person.Surname != value)
                {
                    Person.Surname = value;
                    NotifyOfPropertyChange(() => Surname);
                }
            }
        }
    }
    

    如果您的模型通过 EF 链接到数据库,它在保存/加载更改等时也很有用。您可以实现保存/撤消或 IsDirty 跟踪:

    public class PersonViewModel : PropertyChangedBase
    {
        private Person person;
        public Person Person
        {
            get { return person; }
            set { person = value; }
        }
    
        private String firstName;
        public String FirstName
        {
            get { return firstName; }
            set
            {
                if (firstName != value)
                {
                    firstName = value;
                    NotifyOfPropertyChange(() => FirstName);
                }
            }
        }
    
        private String surname;
        public String Surname
        {
            get { return surname; }
            set
            {
                if (surname != value)
                {
                    surname = value;
                    NotifyOfPropertyChange(() => Surname);
                }
            }
        }
    
        public void SaveToModel()
        {
            Person.FirstName = FirstName;
            Person.Surname = Surname;
            // trigger EF save?
        }
    
        public void LoadFromModel()
        {
            FirstName = Person.FirstName;
            Surname = Person.Surname;
        }
    }
    

    有关在模型上实施 PropertyChange 的优缺点的大量讨论,请参阅这些问题:

    MVVM duplicating Model properties in ViewModel

    In MVVM model should the model implement INotifyPropertyChanged interface?

    In MVVM should the ViewModel or Model implement INotifyPropertyChanged?

    两者都做完后,我建议您将通知排除在模型之外,并尽量使其尽可能简单。

    【讨论】:

    • 为辛勤工作点赞,可能对一些新人有用。我做过属性镜像,但它有它的缺陷。如果其他东西(如计算或更新后台线程)引用了 Person 对象并更改了他的名称,则 PersonViewModel 不会知道它,因为 Person 本身不会触发 PropertyChanged 事件。当我尝试让 PropertyChangedBase 继承类时,当对类的属性进行任何更改时,所有具有引用的视图模型都会更新。您的答案也是代码优先的方法,但不幸的是,我有 db-first
    猜你喜欢
    • 2011-05-19
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-08
    相关资源
    最近更新 更多