C# MVVM 把数据访问层放在哪里?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1717621/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
MVVM where to put Data Access Layer?
提问by Dan Black
I am investigating WPF's MVVM design pattern. But am unsure where to put the Data Acess code?
我正在研究 WPF 的 MVVM 设计模式。但不确定将数据访问代码放在哪里?
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?
在我看过的一些例子中,数据访问是直接在 ViewModel 中执行的。在 ViewModel 中放入 linq to sql 之类的东西似乎很奇怪?其他例子有一个单独的数据访问项目,这看起来更像吗?
Is this there a general approach? I feel like I am missing something here!
这是有通用方法吗?我觉得我在这里错过了一些东西!
Thanks
谢谢
采纳答案by Lukasz
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.
我会添加另一层,基本上你想要的是一个数据工厂。您想创建一组类,这些类将为您 CRUD 到数据库并将干净的 POCO 对象返回给 ViewModel。
A good example to look at would the Nerd Dinnerbook. 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.
一个很好的例子是书呆子晚餐书。它涵盖了 MVC 而不是 MVVM,但模式非常相似,它们在该解决方案中访问数据的方式将是一个很好的起点。
Hope this helps.
希望这可以帮助。
回答by GraemeF
MVVM stands for Model, View, and ViewModel. The piece you are missing is the Model, which is where your data access code lives.
MVVM 代表Model、View和ViewModel。您缺少的部分是模型,它是您的数据访问代码所在的位置。
The ViewModel takes the Model and presents it to the View for display, so typically you would have something like this:
ViewModel 接受 Model 并将其呈现给 View 以进行显示,因此通常您会有这样的事情:
class PersonModel : IPerson
{
// data access stuff goes in here
public string Name { get; set; }
}
class PersonViewModel
{
IPerson _person;
public PersonViewModel(IPerson person)
{
_person = person;
}
public Name
{
get { return _person.Name; }
set { _person.Name = value; }
}
}
The PersonView
would then bind to the properties of the PersonViewModel
rather than directly to the model itself. In many cases you might already have a data access layer that knows nothing about MVVM (and nor should it) but you can still build ViewModels to present it to the view.
在PersonView
随后将绑定到的属性PersonViewModel
,而不是直接到模型本身。在许多情况下,您可能已经拥有一个对 MVVM 一无所知(也不应该知道)的数据访问层,但您仍然可以构建 ViewModel 以将其呈现给视图。
回答by Kristoffer
Data access should notbe 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.
使用某种映射器将您的视图模型(MVVM 中的 VM)映射到您的模型(第一个 M)。可以使用工厂模式创建模型中的新对象。创建后,您可以使用存储库模式将它们存储在数据库中。然后,存储库将代表您的数据访问层。在您的存储库中,您可以使用 O/R 映射器,如 NHibernate 或实体框架。
EDIT:
I see that GraemeF suggests putting the data access code in the model. This is a NOTa 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.
编辑:
我看到 GraemeF 建议将数据访问代码放在模型中。这不是一个好方法,因为如果您要从例如 SQL Server 移动到 Oracle 或 XML 文件,这将迫使您更新域模型。域对象不必担心它们是如何持久化的。存储库模式将域与其持久性隔离开来。
回答by Ryan Emerle
Your ViewModel should be a thin layer that just services the view. My rule of thumb: if it has to do with the presentation of the UI, then it belongs in the ViewModel, otherwise it should be in the Model.
您的 ViewModel 应该是一个只为视图提供服务的薄层。我的经验法则:如果它与 UI 的呈现有关,那么它属于 ViewModel,否则它应该在 Model 中。
回答by devuxer
Here's how I've been organizing my MVVM w/ LINQ projects:
以下是我使用 LINQ 项目组织 MVVM 的方式:
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.
模型- 我认为模型是系统的状态。它提供数据接口,并跟踪系统状态。Model 不知道 ViewModel 或 View——它只是为其数据和各种事件提供一个公共接口,让消费者(通常是 ViewModels)知道状态何时发生变化。
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.
ViewModel- ViewModel 负责组织或构建 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.
视图- 视图是 UI 的实际外观和感觉。它包含所有内置和自定义控件、它们的排列方式以及它们的样式。它知道 ViewModel,但只是为了绑定到它的属性。
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.
网关- 这是直接解决您的问题的部分。网关(这基本上是我所说的“DataAccessLayer”)是它自己的独立层。它包含所有代码(包括 LINQ 查询)到 CRUD 或从/向数据源(数据库、XML 文件等)选择、插入、更新和删除数据。它还为模型提供了一个公共接口,允许模型专注于维护系统状态,而不必关心更新数据源所需的细节(即查询)。
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:
数据访问类- 在 C# 中,这些是对基本数据对象建模的非常简单的类。当您使用 LINQ 查询选择某些内容时,您通常会创建一个IEnumerable<T>
或List<T>
whereT
是您的数据对象之一。数据对象的一个例子是:
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].
缺点是对于小项目来说可能有点矫枉过正。您最终为公共接口创建了许多基础设施,这些基础设施基本上通过多个层传递一个单一的愿望。所以,你最终可能会出现这样的场景:[用户点击提交,ViewModel 告诉 Model 到 AddNewPerson,Model 告诉 Gateway 到 InsertPerson] 而不是这样的场景 [用户点击提交,ViewModel 直接向数据库添加新记录]。
Hope that helps.
希望有帮助。
回答by jbe
The WPF Application Framework (WAF)contains a sample application that shows how the Model-View-ViewModel (MVVM) pattern might be used in combination with the Entity Framework.
在WPF应用程序框架(WAF)包含一个示例应用程序,展示了如何模型-视图-视图模型(MVVM)模式可能组合使用实体框架。