Translation [MVC 5 + EF 6] 2: Base additions and deletions (CRUD)

Source: Internet
Author: User
Tags actionlink

Original: Implementing Basic CRUD functionality with the Entity Framework in ASP. NET MVC Application

1. Modify views\student\details.cshtml:

@model contosouniversity.models.student@{viewbag.title = "Details";}<H2>Details</H2><Div>    <h4>Student</h4>    <HR/>    <DLclass= "Dl-horizontal">        <DT>@Html. displaynamefor (model = model. LastName)</DT>        <DD>@Html. displayfor (model = model. LastName)</DD>        <DT>@Html. displaynamefor (model = model. Firstmidname)</DT>        <DD>@Html. displayfor (model = model. Firstmidname)</DD>        <DT>@Html. displaynamefor (model = model. EnrollmentDate)</DT>        <DD>@Html. displayfor (model = model. EnrollmentDate)</DD>        <DT>@Html. displaynamefor (model = model. enrollments)</DT>        <DD>            <Tableclass= "Table">                <TR>                    <th>Course Title</th>                    <th>Grade</th>                </TR>@foreach (var item in model.enrollments) {<TR>                        <TD>@Html. displayfor (ModelItem = Item. Course.title)</TD>                        <TD>@Html. displayfor (ModelItem = Item. Grade)</TD>                    </TR>                }            </Table>        </DD>    </DL></Div><P>@Html. ActionLink ("edit", "edit", new {id = model.id}) | @Html. ActionLink ("Back to List", "Index")</P>

2. Modify the Controllers\studentcontroller.cs create:

[Httppost][validateantiforgerytoken] PublicActionResult Create ([Bind (Include ="LastName, Firstmidname, EnrollmentDate")]student Student) {Try    {        if(modelstate.isvalid) {db.            Students.add (student); Db.            SaveChanges (); returnRedirecttoaction ("Index"); }    }    Catch(dataexception/*Dex*/)    {        //Log the error (uncomment DEX variable name and add a line here to write a Log.Modelstate.addmodelerror ("","unable to save changes. Try again, and if the problem persists see your system administrator."); }    returnView (student);}

  ValidateAntiForgeryTokenThe Cross-site property is used to prevent cross-site request forgery attacks (forgery), and in the view you need to add @Html. AntiForgeryToken () to implement this feature.

  The Bind property is used to prevent incoming extra fields. In the bind attribute Include , the parameter lists the field whitelist (whitelist), and theExclude parameter lists the field blacklist (blacklist). Using the include parameter is more secure because new fields are not automatically blacklisted when we add new fields to the entity.

On the edit page, we can first read the entity from the database and then callTryUpdateModel,传入明确被允许的字段列表来防止传入多余的字段。

Another way to prevent passing in extra fields is to use the view model , which contains only the fields that we want to update in the view model. When the MVC model is bound, we can use a tool like AutoMapper to copy the values from the view model to the entity instance. Then use DB for the entity instance. Entry, change its state to unchanged, and then include each field ("PropertyName") in the view model. ismodified) is set to true. This method can be used to create and edit pages.

  The code for the views\student\create.cshtml page is similar to the details.cshtml page, and the difference isEditorFor和ValidationMessageFor取代了DisplayFor:

<class= "Form-group">    @Html. labelfor (model = model. LastName, new {@class = "Control-label col-md-2"})    <class= "Col-md-10"  >        @Html. editorfor (model = model. LastName)        @Html. validationmessagefor (model = model. LastName)    </div></div> 

To run the project:

The error message comes from the default service-side (server-side) authentication:

                if (modelstate.isvalid)                {                    db. Students.add (student);                    Db. SaveChanges ();                    Return redirecttoaction ("Index");                }

3. Modify the controllers\studentcontroller.cs edit:

[HttpPost, ActionName ("Edit")][validateantiforgerytoken] PublicActionResult Editpost (int?ID) {    if(id = =NULL)    {        return NewHttpstatuscoderesult (httpstatuscode.badrequest); }    varStudenttoupdate =db.    Students.find (ID); if(TryUpdateModel (Studenttoupdate,"",       New string[] {"LastName","Firstmidname","enrollmentdate" }))    {        Try{db.            SaveChanges (); returnRedirecttoaction ("Index"); }        Catch(dataexception/*Dex*/)        {            //Log the error (uncomment DEX variable name and add a line here to write a Log.Modelstate.addmodelerror ("","unable to save changes. Try again, and if the problem persists, see your system administrator."); }    }    returnView (studenttoupdate);}

The modified code is a best practice for blocking incoming extra fields. The original code was automatically added to the scaffold, the bind attribute was added and the modified tag was added for the model bound entity, so the code is no longer recommended because the Bind property automatically cleans up the original values of fields not listed in the Include parameter. Future MVC scaffolding will be updated without the bind attribute being generated for the edit method.

The modified code gets the entity that already exists and updates the entity based on data calls entered by the user TryUpdateModel . EF automatically adds modified tags to new entities. When the SaveChanges method is called, the modified tag causes EF to generate SQL to update the database. The method ignores concurrency conflicts, and all columns that include values that do not change will be updated (subsequent tutorials will show how to handle concurrency conflicts if we only want to update the specified column to set the entity to unchanged, and set the column that needs to be changed to modified).

The data context keeps track of whether the state of the entity in memory is consistent with the state of the corresponding row in the database, and the tracking information will determine whenSaveChanges被调用时产生什么样的动作。例如,当我们通过Add方法添加一个实体时,这个实体的状态将会标记为Added,当调用SaveChanges放方式,数据库上下文将会调用INSERT命令。实体的状态列表:

    • Added: The entity does not yet exist in the database, and the SaveChanges method produces an INSERT statement.
    • Unchanged:SaveChanges方法将不会产生任何动作。当我们从数据库中获取一个实体时,这是该实体的初始状态。
    • Modified: Some or all of the columns of an entity are changed, and the SaveChanges method produces an UPDATE statement.
    • Deleted: The entity is marked for deletion, and the SaveChanges method produces a DELETE statement.
    • Detached: The entity is not tracked by the database context.

In a desktop application, the change in entity state is automatic. In the desktop nature of the program, change the value of a part of an entity's field, the state of the entity is automatically marked as Modified . Then, when we call SaveChanges , EF will generate only the SQL that has changed the field.

However, the nature of the disconnection (disconnected) of the Web application does not allow this continuous sequence (continuous sequence). When the page rendering is complete, the entities read by DbContext will be released. When HttpPost Edit called, the new request creates a new DbContext instance, so we must manually set the state of the entity to Modified . When called SaveChanges , EF will update all columns, and the database context cannot know which columns we are updating.

If we only want to update the columns that are actually changed, we need to save the original values in some way (such as a hidden Attach field), then call the method, change the value of the entity to the new value, and then call SaveChanges .

4. Modify the controllers\studentcontroller.cs Delete:

[HttpPost, ActionName ("Delete")] [Validateantiforgerytoken] PublicActionResult deleteconfirmed (intID) {Try{Student Student=db.                Students.find (ID); Db.                Students.remove (student); Db.            SaveChanges (); }            Catch(dataexception/*Dex*/)            {                //Log the error (uncomment DEX variable name and add a line here to write a Log.                returnRedirecttoaction ("Delete",New{id = id, savechangeserror =true }); }            returnRedirecttoaction ("Index"); }

To raise the performance of concurrent programs, we need to avoid unnecessary queries and replace the Find and remove methods above with the following code:

New Student () {ID == entitystate.deleted;

5. Close the database connection :

protected Override void Dispose (bool  disposing) {    db. Dispose ();     Base . Dispose (disposing);}

The Controller base class implements the IDisposable interface, so you can override the Dispose method to release the context instance.

6. Transaction :

The EF supports transactions by default if you modify multiple rows or tables at the same time and callSaveChanges,EF会保证这些修改同时执行成功或失败。

Translation [MVC 5 + EF 6] 2: Base additions and deletions (CRUD)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.