请教wpf MVVM模式下的Model与ViewModel与Ef 中的Entity

zaaserz 2020-03-06 04:06:47
我今天敲代码时候敲着敲着突然想到一个问题,在MVVM模式中Model与ViewModel的使用,以及这个model是不是Ef中的Entity。
我wpf学习的时间不长,能够理解它的绑定机制,目前我是直接把Ef的Entity作为Model传递进ViewModel中,然后绑定至View中。我感觉我这个状态应该不对。因为为了实现类属性更改通知,我把Entity集成了INotifyPropertyChanged接口。单如果不这样做的话我在项目实现中不知道该如何去做,比如班级内有好多学生现在要做一个界面进行编辑班级与学生的信息。我现在的做法是直接将班级对象(内包含学生对象集合)传递给ViewModel,然后ViewModel将班级对象绑定到View上,这样在View中的修改可以直接体现到Model也就是班级这个对象上,然后我再对班级这个对象进行保存就行啦。这样感觉很方便,但感觉这样不是正确的做法。
因为我的项目基本上都是单机版的没有服务器与客户端之分,所以这个Model直接就是从数据库中拿到的。从数据库中拿到后将其映射到entity上那这个entity如果不应该传递到ViewModel中的话,那在ViewModel中难道要建立好多属性与entity的属性进行对应么?
...全文
474 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
kinglucifa 2020-03-09
  • 打赏
  • 举报
回复
Ef查询结果输出类型为下面定义的学生Model,在viewmodel中实例化该model,然后将其绑定到view上。 public class Students { public string name{ get; set; } public int age{ get; set; } }
正怒月神 2020-03-09
  • 打赏
  • 举报
回复
引用 10 楼 zaaserz 的回复:
[quote=引用 9 楼 正怒月神 的回复:] 首先,我们先明确一些概念。 楼主其实理解的没问题。 ef model属于数据库的映射字段,甚至说可能很接近。 vm属于view专属的,这是ef model产生的对应前台view使用的 vm。 然后,我们考虑ef和vm的INotifyPropertyChanged的问题。 由于我不使用wpf,而是前台vue+后端。所以我可能更倾向于 vm实现 INotifyPropertyChanged。 ef model则不实现。 如果存在vm和ef model的字段基本一致,那么可以使用 automapper之类的直接映射。 因为我个人认为,vm和ef model还是存在需要处理的逻辑。 而vm和ef model需要针对性的处理。一个model可能会产生多个vm来对应不同的view。 不过,哪怕你ef model和vm都实现了INotifyPropertyChanged,我个人感觉也没什么问题。
感谢回复,因为我这边做的很多都是单机版的所以前后台之分很弱,基本上直接都是直接拿Ef model 放到ViewModel中做属性,后来又因为需要更改model 中的属性,为了让View中自动更改,就让ef model继承了INotifyPropertyChanged接口~~~写着写着就发现Ef model 内 做了好多不属于自己的工作,然后就想着优化一下它,但是就发现它和viewmodel 耦合很大,再建立一个中间类进行映射的话会需要写好多映射代码,所以就产生了这个问题。现在我是不是可以这样理解,规范情况下应该使用一个中间类进行映射。如果为了偷懒或者不计较那么多也可以直接将ef model 安装我现在的做法继承INotifyPropertyChanged后直接传递个viewmodel 进行绑定。[/quote] 如果对于业务没有问题或者bug,那么其实使用第三方的automapper的类库或者你说的model直接实现INotifyPropertyChanged,应该都没有太大问题。 我感觉都可以。
zaaserz 2020-03-09
  • 打赏
  • 举报
回复
引用 9 楼 正怒月神 的回复:
首先,我们先明确一些概念。 楼主其实理解的没问题。 ef model属于数据库的映射字段,甚至说可能很接近。 vm属于view专属的,这是ef model产生的对应前台view使用的 vm。 然后,我们考虑ef和vm的INotifyPropertyChanged的问题。 由于我不使用wpf,而是前台vue+后端。所以我可能更倾向于 vm实现 INotifyPropertyChanged。 ef model则不实现。 如果存在vm和ef model的字段基本一致,那么可以使用 automapper之类的直接映射。 因为我个人认为,vm和ef model还是存在需要处理的逻辑。 而vm和ef model需要针对性的处理。一个model可能会产生多个vm来对应不同的view。 不过,哪怕你ef model和vm都实现了INotifyPropertyChanged,我个人感觉也没什么问题。
感谢回复,因为我这边做的很多都是单机版的所以前后台之分很弱,基本上直接都是直接拿Ef model 放到ViewModel中做属性,后来又因为需要更改model 中的属性,为了让View中自动更改,就让ef model继承了INotifyPropertyChanged接口~~~写着写着就发现Ef model 内 做了好多不属于自己的工作,然后就想着优化一下它,但是就发现它和viewmodel 耦合很大,再建立一个中间类进行映射的话会需要写好多映射代码,所以就产生了这个问题。现在我是不是可以这样理解,规范情况下应该使用一个中间类进行映射。如果为了偷懒或者不计较那么多也可以直接将ef model 安装我现在的做法继承INotifyPropertyChanged后直接传递个viewmodel 进行绑定。
正怒月神 2020-03-09
  • 打赏
  • 举报
回复
首先,我们先明确一些概念。 楼主其实理解的没问题。 ef model属于数据库的映射字段,甚至说可能很接近。 vm属于view专属的,这是ef model产生的对应前台view使用的 vm。 然后,我们考虑ef和vm的INotifyPropertyChanged的问题。 由于我不使用wpf,而是前台vue+后端。所以我可能更倾向于 vm实现 INotifyPropertyChanged。 ef model则不实现。 如果存在vm和ef model的字段基本一致,那么可以使用 automapper之类的直接映射。 因为我个人认为,vm和ef model还是存在需要处理的逻辑。 而vm和ef model需要针对性的处理。一个model可能会产生多个vm来对应不同的view。 不过,哪怕你ef model和vm都实现了INotifyPropertyChanged,我个人感觉也没什么问题。
kinglucifa 2020-03-09
  • 打赏
  • 举报
回复
在vm里面实例化下面的Source, 在View里面列表控件直接绑定Source就可以了,文本框类控件的话在vm里面定义属性绑定 private ObservableCollection<Student> _soruce; public ObservableCollection<Student> Source { get { return this._soruce; } set { this.SetProperty(ref this._soruce, value, "Source"); } }
zaaserz 2020-03-09
  • 打赏
  • 举报
回复
引用 6 楼 kinglucifa 的回复:
[quote=引用 5 楼 zaaserz 的回复:] [quote=引用 3 楼 kinglucifa 的回复:] Ef查询结果输出类型为下面定义的学生Model,在viewmodel中实例化该model,然后将其绑定到view上。 public class Students { public string name{ get; set; } public int age{ get; set; } }
但是如果想要Students属性的更改也能通知view需要让类继承INotifyPropertyChanged,这样这个Students就需要继承下接口INotifyPropertyChanged,我现在问的是这样的设计是否是正确的。[/quote] Students是Model,不需要继承接口INotifyPropertyChanged,只要在ViewModel里继承就可以了,在vm里面实例化Model,封装为属性绑定到view上[/quote] 如果不去继承INotifyPropertyChanged接口,在vm中对Strudents的属性进行更改后,view并不会体现出来。比如更改了Strudents的name属性如果没有继承INotifyPropertyChanged接口,在view中name属性不会对应更改。
kinglucifa 2020-03-09
  • 打赏
  • 举报
回复
引用 5 楼 zaaserz 的回复:
[quote=引用 3 楼 kinglucifa 的回复:] Ef查询结果输出类型为下面定义的学生Model,在viewmodel中实例化该model,然后将其绑定到view上。 public class Students { public string name{ get; set; } public int age{ get; set; } }
但是如果想要Students属性的更改也能通知view需要让类继承INotifyPropertyChanged,这样这个Students就需要继承下接口INotifyPropertyChanged,我现在问的是这样的设计是否是正确的。[/quote] Students是Model,不需要继承接口INotifyPropertyChanged,只要在ViewModel里继承就可以了,在vm里面实例化Model,封装为属性绑定到view上
zaaserz 2020-03-09
  • 打赏
  • 举报
回复
引用 3 楼 kinglucifa 的回复:
Ef查询结果输出类型为下面定义的学生Model,在viewmodel中实例化该model,然后将其绑定到view上。 public class Students { public string name{ get; set; } public int age{ get; set; } }
但是如果想要Students属性的更改也能通知view需要让类继承INotifyPropertyChanged,这样这个Students就需要继承下接口INotifyPropertyChanged,我现在问的是这样的设计是否是正确的。
github_36000833 2020-03-09
  • 打赏
  • 举报
回复
模式,是为了提高效率的(维护效率,测试效率,开发效率,团队效率)等。 如果你觉得硬套模式不妥,无需过于纠结为了模式而模式。开发实践会让你更好理解模式的应用。 话说回来,Entity非常靠近数据库数据结构。隔离UI展现和内部数据结构(区分你说的Entity和ModelView),可以是优先选择。
zaaserz 2020-03-07
  • 打赏
  • 举报
回复
引用 1 楼 tangyanzhi1111 的回复:
其实 entity 的model 就是你 mvvm 里面的viewmodel
那直接在entity类上继承INotifyPropertyChanged接口,然后将其绑定到view上,这样好么?我总感觉这样虽然比较方便但是耦合更高啦。
江湖评谈 2020-03-06
  • 打赏
  • 举报
回复
其实 entity 的model 就是你 mvvm 里面的viewmodel

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧