简体   繁体   English

实体框架和与MVC的关系

[英]Entity Framework and the relationship with MVC

I am trying to understand the whole MVC/EF relationship. 我试图了解整个MVC / EF关系。 If I create a Entity Model that would only interact with the database (since you shouldnt pass you entity model to a view), then a class for the Model, and finally a view model all shown below. 如果我创建一个只与数据库交互的实体模型(因为你不应该将实体模型传递给视图),那么Model的类,最后是一个视图模型,如下所示。 My only question is it seems redundant to have the second class, the only different in the examples I have seen is that they apply data annotations to that class since it is interacting with the view. 我唯一的问题是拥有第二个类似乎是多余的,我看到的例子中唯一不同的是它们将数据注释应用于该类,因为它与视图交互。 Why is it so important to make sure that entity objects arent exposed at the view layer? 为什么确保实体对象不暴露在视图层是如此重要?

I havent actually started writing a project yet, but I assume that you would use the Entity model for interacting with a database then cast it into a ProductModel to pass to the view is this the correct logic? 我还没有真正开始编写项目,但是我假设您将使用Entity模型与数据库进行交互,然后将其转换为ProductModel以传递给视图,这是正确的逻辑吗?

Entity Model: 实体模型:

public class Product 
{
    [Key()]
    public int ID { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public double Price { get; set; }
}

Model: 模型:

public class ProductModel
{
    public int ID { get; set; }
    [StringLength(50)]
    [Required(ErrorMessage = "Product Name is required.")]
    [Display(Name = "Product Name")]
    public string Name { get; set; }
    public string Description { get; set; }
    public double Price { get; set; }
}

ViewModel: 视图模型:

public class ProductViewModel
{
    Product myProduct { get; set; }\
    //Plus any other properties I may need for the view.
}

UPDATE: 更新:

In the example I have been reading they also have a DBContext set as follows. 在我一直在阅读的例子中,他们也有一个DBContext设置如下。 So is the ProductModel class useless then? 那么ProductModel类是否无用呢?

public class MyAppContext : DbContext
{
    public MyAppContext()
        : base("name=DBConnection")
    { 
    }

    public DbSet<Product> Products { get; set; }

 }

There's times, and particularly on simple models, where a view model may not be required. 有时候,特别是在简单模型上,可能不需要视图模型。 But, and a big "but", I've found very few instances of that situation and even then, I later generally find a need to go back and create a view model, anyways. 但是,和一个很大的“但是”,我发现很少有这种情况的实例,即便如此,我后来普遍发现需要回去创建一个视图模型,无论如何。 Having a specialized view model is safer, simpler and easier all-around. 拥有专业的视图模型更安全,更简单,更容易全方位。

You might look at it as extra work, but think of it in terms of separation of concerns (which is the whole point of MVC). 您可能会将其视为额外的工作,但从关注点的分离(这是MVC的全部要点)来考虑它。 If I want to present a SelectList for an input, for example, I can either add it to ViewBag or to my model. 例如,如果我想为输入提供SelectList,我可以将其添加到ViewBag或我的模型。 If I add it to ViewBag, I lose strong-typing which is never ideal, but it doesn't belong on my database-tracked entity, either. 如果我将它添加到ViewBag,我将失去强类型,这绝不是理想的,但它也不属于我的数据库跟踪实体。 Having a view model let's me put this information exactly where it should go: a strongly-typed model that exists to serve the view and only to serve the view. 有了一个视图模型,让我把这些信息准确地放在它应该去的地方:一个强类型模型,它存在于服务视图并且只为视图提供服务。

Or, consider validation: what if I want a field required for the database (non-null), but I want to make this optional for the user, and fill it with some business logic myself behind the scenes if the user opts not to specify. 或者,考虑验证:如果我想要数据库所需的字段(非空)怎么办,但我想让用户选择此选项,如果用户选择不指定,则在幕后填写一些业务逻辑。 The view model can handle that abstraction easily whereas adding it to the entity, itself, would add a huge layer of complexity. 视图模型可以轻松处理该抽象,而将其添加到实体本身则会增加大量复杂性。

Nothing is required, of course. 当然,没有必要。 You can always set up your project however you like, but best-practices are best-practices for a reason: developers just like you, time and again, have ran into the same issues and coalesced around a workable solution. 你可以随时设置你的项目,但最好的做法是最好的做法,原因是:开发人员喜欢你,一次又一次,遇到了同样的问题,并围绕一个可行的解决方案进行了合并。 You might be able to avoid view models for a time, but eventually, you'll run into the same roadblocks and incorporate them anyways, so just do it right from the start and make your life easier. 您可能会在一段时间内避开视图模型,但最终,您将遇到相同的障碍并将它们合并到一起,所以只需从一开始就做到这一点,让您的生活更轻松。

There are two major reasons I create a model class, separate from my entity. 我创建一个模型类有两个主要原因,与我的实体分开。

  1. As you mentioned, attributes. 正如你所提到的,属性。 You may want to reuse your entities in several applications and they may not use the same attributes. 您可能希望在多个应用程序中重用您的实体,并且它们可能不使用相同的属性。 You don't want to pollute your entities with these. 您不希望用这些污染您的实体。

  2. Depending on them ORM, your entities may require a base class. 根据它们的ORM,您的实体可能需要基类。 Or there might be attributes, or other customizations that you have to apply to the entities. 或者可能存在必须应用于实体的属性或其他自定义。 This could cause there to be difficulties when testing your Business Logic. 这可能会导致在测试业务逻辑时遇到困难。 Additionally, if you change ORMs or something in your ORM changes, you will keep that change isolated from the rest of the application. 此外,如果您更改ORM中的ORM或某些更改,您将保持该更改与应用程序的其余部分隔离。

Basically, you are isolating the different layers of your application and protecting one layer from changes made in another. 基本上,您正在隔离应用程序的不同层,并保护一层不受另一层的更改。

You need Product class , ProductViewModel class then your DbContext . 您需要Product classProductViewModel class然后是您的DbContext If you are doing this for the first time, read Pro ASP.NET MVC 3 Framework, Third Edition 如果您是第一次这样做,请阅读Pro ASP.NET MVC 3 Framework,第三版

or 要么

Pro Asp.Net Mvc 4 Pro Asp.Net Mvc 4

They have a detailed information about MVC and both books have a Real Application tutorial you can follow from start to finish including deployment. 他们有关于MVC的详细信息,这两本书都有一个Real Application tutorial you can follow从头到尾Real Application tutorial you can follow ,包括部署。

You will also learn about Unit Testing and other MVC tools such as Dependency Injection (Ninject) and Moq 您还将学习单元测试和其他MVC工具,例如依赖注入(Ninject)和Moq

In Addition to the answers above, another point that hasnt been mentioned to to prevent data being sent to the view/client that doesnt need to be. 除了上面的答案之外,还没有提到另一点来防止数据被发送到不需要的视图/客户端。

for example suppose your product model contains the price you pay your supplier to purchase the product. 例如,假设您的产品型号包含您向供应商支付的购买产品的价格。 you dont want your customers to see this data, but if it is included in the model sent to the view - even if you don't display that field - they can assess it. 您不希望您的客户看到此数据,但如果它包含在发送到视图的模型中 - 即使您没有显示该字段 - 他们也可以对其进行评估。 this is a case where you would use a different view model and copy the data from the ef/database model to the view model before sending it to the view. 在这种情况下,您将使用不同的视图模型并将数据从ef /数据库模型复制到视图模型,然后再将其发送到视图。

sometimes you can end up with a DBcontext class, an EF/database class/Model and several viewmodels each holding a different subset of the data from the database model. 有时您最终会得到一个DBcontext类,一个EF /数据库类/模型和几个视图模型,每个视图模型都包含数据库模型中不同的数据子集。

you can also find yourself with a viewmodel that holds data from several Database models, you offten see this where the view uses lists or dropdowns as an alternative to sending the list options in the viewbag. 您还可以使用包含来自多个数据库模型的数据的视图模型找到自己,您可以看到视图使用列表或下拉列表作为在viewbag中发送列表选项的替代方法。

The ViewModel is going to be what actually gets passed to/from the browser, often via JSON if you're building something that can update in place/save in place. ViewModel将实际传递到浏览器或从浏览器传递,通常是通过JSON,如果您正在构建可以就地更新/保存到位的东西。 So: 所以:

  • ASP.Net MVC has some limitations around what it can produce/consume over JSON (and its limitations differ slightly in each direction); ASP.Net MVC对JSON可以产生/消耗的内容有一些限制(其限制在每个方向上略有不同); you can use a ViewModel to work around that 您可以使用ViewModel来解决这个问题

  • The size of the data you pull back from the database may not be what needs to get to the browser - for example you might need to pull back some extra fields and check them before passing it on, but only want to pass on a subset - the ViewModel is the subset. 从数据库中提取的数据大小可能不是需要访问浏览器的数据 - 例如,您可能需要撤回一些额外的字段并在传递之前检查它们,但只想传递一个子集 - ViewModel是子集。

  • Some natural structures in JSON are not really available in a database - for example you might have the equivalent of a Dictionary stored in your Model, as for example one table with some values, and another table with an FK pointing back to it, an Id, and a string value - but for the browser to leverage it you might just need that string value. JSON中的一些自然结构在数据库中实际上不可用 - 例如,您可能具有存储在模型中的等效的Dictionary,例如一个具有某些值的表,另一个具有指向它的FK的表,Id和字符串值 - 但是对于浏览器来利用它,您可能只需要该字符串值。 So in the ViewModel you represent that all with a simple Dictionary (which ends up as a simple JS object on the client). 因此,在ViewModel中,您使用简单的Dictionary(最终作为客户端上的简单JS对象)表示所有这些。

  • Often things like Date formatting are weak on the client or flimsy by depending on the client having an accurate system clock, etc. I frequently use a String in my ViewModel where I have a DateTime in my Model and translate from UTC to their timezone and format it nicely on the server before it arrives in their browser. 通常,日期格式化在客户端上很弱或者取决于具有准确系统时钟等的客户端。我经常在我的ViewModel中使用String,我在模型中有一个DateTime并从UTC转换为他们的时区和格式它在服务器到达浏览器之前就很好了。

  • Sometimes you need to avoid exposing parts of the Model to the browser; 有时您需要避免将模型的某些部分暴露给浏览器; for example in some systems if you exposed the row Id to the browser you could create a security risk. 例如,在某些系统中,如果将行Id暴露给浏览器,则可能会产生安全风险。 A ViewModel makes it trivial to hide portions of your Model. ViewModel使得隐藏模型的部分变得微不足道。

See also: how to design ViewModel 另请参见: 如何设计ViewModel

To start, there is something missing and combined techniques, one is to abstract completelly the DAL from all other layer, this is a technique. 首先,有一些缺失和组合技术,一个是从所有其他层完全抽象DAL,这是一种技术。 But also there is other technique that can be used; 但也有其他技术可以使用; use the "Entities" classes as domain classes. 使用“实体”类作为域类。 On a simple scenario we always use the domain classes on the bussiness layer to apply all the bussiness rules. 在一个简单的场景中,我们总是使用业务层上的域类来应用所有业务规则。 this will help us a lot to combine the testability throught layers and avoiding unuseful links between layers without increasing a lot of lines of code/number of classes. 这将有助于我们在层中结合可测试性并避免层之间的无用链接,而不会增加很多代码行数/类数。

Also this approach to have this domain objects (domain classes) throught all the layers will make you things a lot easier when you are working with MVC, because this classes can have data annotations that will be used by: 此方法通过所有层使用此域对象(域类)将使您在使用MVC时更容易,因为此类可以具有将被以下方式使用的数据注释:

  1. Views for validations 验证视图
  2. Database for integrity 数据库的完整性

Also to understand the concept and use of this type of classes there is something that we need to pay attention. 另外,为了理解这类课程的概念和用法,我们需要注意一些事项。 If we are using POCO's as our entities and domain classes, this same classes are not the same classes that Entity Framework will use when interpreting queries to the DB. 如果我们使用POCO作为我们的实体和域类,那么这些相同的类与Entity Framework在向DB解释查询时将使用的类不同。 Instead EF will create dynamic classes (derived from the POCO) that represent that domain object as a entity and load all the virtual fields, typically the related entities. 相反,EF将创建动态类(派生自POCO),该动态类将该域对象表示为实体并加载所有虚拟字段,通常是相关实体。

And you will be saving code of classes and trivial remapping. 并且您将保存类的代码和简单的重新映射。

Hope this helps 希望这可以帮助

Why is it so important to make sure that entity objects arent exposed at the view layer? 为什么确保实体对象不暴露在视图层是如此重要?

It isn't. 事实并非如此。 For a simple CRUD controller, it is often easier to just pass in the entity object. 对于简单的CRUD控制器,通常更容易传入实体对象。 For a more complex page you may be interacting with more than one Entity object / type at the same time. 对于更复杂的页面,您可能同时与多个Entity对象/类型进行交互。 How would you pass information about both objects without creating a new model class? 如何在不创建新模型类的情况下传递有关两个对象的信息?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 与Entity Framework 5和.net MVC 4的关系 - relationship with Entity Framework 5 and .net MVC 4 实体框架MVC中的一对一关系 - One to One relationship in Entity Framework MVC ASP.NET MVC 和 Entity Framework——实体关系问题 - ASP.NET MVC and Entity Framework - entity relationship problem 了解.net mvc(实体框架)中特定关系的级联删除? - Understanding cascade delete in a specific relationship in .net mvc (entity framework)? mvc和带有ApplicationUser表的实体框架中的一对一或一对零关系 - one to one or one to zero relationship in mvc and entity framework with ApplicationUser table ASP.NET MVC 5和实体框架多对多关系 - ASP.NET MVC 5 & Entity Framework many to many relationship 使用Entity Framework和MVC将记录插入具有主/从关系的表中 - Insert records into tables with master/detail relationship with Entity Framework and MVC ASP.NET MVC-实体框架多对多关系,插入数据 - Asp .NET MVC - Entity Framework many to many relationship, insert data ASP.net MVC实体框架更新多对多关系 - ASP.net MVC Entity framework update Many to Many relationship 与实体框架和 MVC 的多对多关系与排序 - Many-to-many relationship with Entity Framework and MVC with ordering
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM