问题描述
我正在研究WPF的MVVM设计模式.但是不确定在哪里放置数据ACESS代码?
在我查看的一些示例中,数据访问直接在ViewModel中执行.在ViewModel中将Linq之类的东西放在SQL上似乎很奇怪吗?其他示例有一个独立的数据访问项目,这似乎更像是吗?
这是一种一般方法吗?我觉得我在这里缺少一些东西!
谢谢
推荐答案
我会添加另一层,从本质上讲,您想要的是数据工厂.您想创建一组将为您挑战数据库的类,并将干净的POCO对象返回到ViewModel.
一个很好的例子,要看书呆子晚餐书.它涵盖MVC而不是MVVM,但模式非常相似,并且它们在该解决方案中访问数据的方式将是一个很好的起点.
希望这会有所帮助.
其他推荐答案
这是我一直在组织w/linq项目的方式:
模型 - 我将模型视为系统状态.它提供了数据的接口,并跟踪系统状态.该模型不知道视图模型或视图 - 它仅提供其数据和各种事件的公共接口,以便消费者(通常是ViewModels)知道状态何时更改.
viewModel - 视图模型负责组织或构造视图所需的所有数据,跟踪视图的状态(例如当前选择的数据网格行),并响应视图上的动作(例如按钮按下).它知道视图需要,但实际上并不了解视图.
视图 - 视图是UI的实际外观和感觉.它包含所有内置和自定义控件,它们的排列方式以及如何样式.它知道ViewModel,但仅是为了结合其属性.
网关 - 这是直接解决您的问题的部分.网关(基本上是我说" DataAccesslayer"的方式)是其自己的单独层.它包含所有代码(包括LINQ查询),以从/到您的数据源(数据库,XML文件等)进行crud或选择,插入,更新和删除数据.它还提供了模型的公共接口,允许该模型专注于维护系统状态,而无需关注更新数据源所需的详细信息(即查询).
.dataAccess类 - 在C#中,这些是非常简单的类,可以对您的元素数据对象进行建模.当您使用LINQ查询选择某些内容时,通常会创建IEnumerable<T>或List<T>,其中T是您的数据对象之一.数据对象的一个示例是:
public class Person { public string Name { get; set; } public int Age { get; set; } }
这样的设计的最大优势是它确实使您的担忧分开了.一切都有专业的工作,而且(通常)很容易知道什么样的事情.
缺点是,对于小型项目而言,它可能过于杀伤.您最终为公共接口创建了许多基础架构,这些基础架构基本上通过几层愿望传递了一个愿望.因此,您可能最终会出现这样的方案:[用户单击"提交",ViewModel告诉Model to AddNewperson,Model告诉Gateway to Insertperson]而不是类似的情况[用户单击"提交",ViewModel,ViewModel将新记录直接添加到数据库中].
希望会有所帮助.
其他推荐答案
数据访问应在视图模型中不是,因为这应该是域模型的特定视图(可能简化)表示.
使用某种类型的映射器将视图模型(MVVM中的VM)映射到您的模型(第一个M).可以使用工厂模式创建模型中的新对象.创建后,您可以使用存储库模式将它们存储在数据库中.然后,存储库将表示您的数据访问层.在您的存储库中,您可以使用NHIBERNATE或实体框架等O/R映射器.
编辑:
我看到Graemef建议将数据访问代码放在模型中.这是一个 不是 一个好方法,因为如果您要从例如. SQL Server到Oracle或XML文件. 域对象不必担心它们的持久性.存储库模式将域与其持久性隔离.
问题描述
I am investigating WPF's MVVM design pattern. But am unsure where to put the Data Acess code?
In some examples I have looked at, data access is performed directly in the ViewModel. It seems odd to put something like linq to sql in the ViewModel? Other examples have a seperate project for Data Access, this seems more like it?
Is this there a general approach? I feel like I am missing something here!
Thanks
推荐答案
I would add another layer, essentially what you want is a data factory. You want to create a set of classes that will CRUD to the database for you and return clean POCO objects to the ViewModel.
A good example to look at would the Nerd Dinner book. It covers MVC not MVVM but the patterns are very similar and the way they access data in that solution would be good starting point.
Hope this helps.
其他推荐答案
Here's how I've been organizing my MVVM w/ LINQ projects:
Model - I think of the Model as the state of the system. It provides an interface to the data, and it keeps track of system status. The Model does not know about the ViewModel or View--it just provides a public interface to its data and various events to let the consumers (usually ViewModels) know when the state has changed.
ViewModel - The ViewModel is in charge of organizing or structuring all the data needed by the View, keeping track of the status of the view (such as the currently selected row of a data grid), and responding to actions on the view (such as button pushes). It knows what the view needs, but it doesn't actually know about the view.
View - The View is the actual look and feel of the UI. It contains all the built-in and custom controls, how they arranged, and how they are styled. It knows about the ViewModel, but only for the purpose of binding to its properties.
Gateway - This is the part that directly addresses your question. The Gateway (which is basically my way of saying "DataAccessLayer") is its own separate layer. It contains all the code (including LINQ queries) to CRUD or select, insert, update, and delete data from/to your data source (database, XML file, etc.). It also provides a public interface to the Model, allowing the Model to focus on maintaining system state without having to concern itself with the details (i.e., the queries) needed to update the data source.
DataAccess Classes - In C#, these are very simple classes that model your elemental data objects. When you select something using a LINQ query, you will usually create an IEnumerable<T> or List<T> where T is one of your data objects. An example of a data object would be:
public class Person { public string Name { get; set; } public int Age { get; set; } }
The big advantage of a design like this is that it really separates your concerns. Everything has a specialized job, and it's (usually) pretty easy to know what kind of thing goes where.
The disadvantage is that it may be overkill for small projects. You end up creating a lot of infrastructure for public interfaces that basically pass a single wish through several layers. So, you might end up with a scenario like this: [user clicks Submit, ViewModel tells Model to AddNewPerson, Model tells Gateway to InsertPerson] instead of a scenario like this [user clicks Submit, ViewModel adds new record to the database directly].
Hope that helps.
其他推荐答案
Data access should not be in the view model, as this is supposed to be a view specific (possibly simplified) representation of the domain model.
Use a mapper of some sort to map your view model (the VM in MVVM) to your model (the first M). New objects in your model can be created using the factory pattern. Once created, you can store them in a database using the repository pattern. The repositories would then represent your data access layer. In your repository you could use an O/R mapper like NHibernate or Entity Framework.
EDIT:
I see that GraemeF suggests putting the data access code in the model. This is a NOT a good approach, as this would force you to update your domain model if you were to move from e.g. SQL Server to Oracle or XML files. The domain objects should not have to worry about how they are persisted. The repository pattern isolates the domain from its persistence.