📜 ⬆️ ⬇️

ASP NET.MVC Lesson 3. Working with the Database

The purpose of the lesson : Learn the basic principles of working with a database. Brief description of the relational database model. Work with the database (creating tables, links in VS 2012). Commands INSERT, UPDATE, DELETE, SELECT. Using LinqToSql and Linq. Create a repository, IRepository, SqlRepository.

What is a DB?

A relational database is a database based on a relational data model. Relationality is a relationship (connection) from the English. relation.

Tables

This is the table:


The table consists of columns and rows. Columns have properties - name, data type.
Tables should have the following properties:

The structure of the table can be written in this form:

')
Connections

Relationships exist between tables. To establish a connection, you must have the following:


Links are of three types:

Now let's figure out how to do it.

Creating a simple schema in the database

Let's create a database in VS 2012:



Let's call it LessonProject, and add 3 tables Role User and UserRole.
Create a Role table:





For string values, we use the type nvarchar (n), where n is the maximum length of the string, usually between 50 and 500. For large text lines, nvarchar (MAX) is used.

Install the primary key:



Set the ID autoincrement:



Similarly, create a User table:
FieldField type
IDint
Emailnvarchar (150)
Passwordnvarchar (50)
AddedDatedatetime
Activateddatedatetime (null)
Activatedlinknvarchar (50)
LastVisitDatedatetime (null)
Avatarpathnvarchar (150) (null)


Create a UserRole table:
FieldField type
IDint
Useridint
RoleIDint


Add links:



Add a new link by clicking Add. Adding links occurs in the table where the foreign keys are located. Expand the Tables and Columns tab and set the table with the primary key, and select the foreign key in the current UserRole table.



In the properties of the INSERT And UPDATE Specification, we set the On Update / On Delete properties of the Cascade:



This is necessary in order to change / delete a column from the Role table, all the rows of the UserRole table associated with this row must be changed or deleted.

We establish a similar connection with the User table.

Thus, the Role and User tables have many to many relationships through the UserRole table. Those. one user may have more than one role, and several users may have the same role.

SELECT, INSERT, UPDATE, DELETE.

Relational databases use SQL query language.

There are 4 basic commands for manipulating data - SELECT, INSERT, UPDATE, DELETE

SELECT - to select data and tables.
Example:
SELECT * FROM User 

INSERT - Adding rows to a table
Example:
 INSERT INTO Role (Code, Name) VALUES (“admin”, “”) 

UPDATE - change the values ​​in the table
Example:
 UPDATE User SET Password=”password1” WHERE ID=1 

DELETE - delete rows from a table.
Example:
 DELETE FROM User WHERE ID =1 


Note: You can learn more about SQL by reference:
http://www.w3schools.com/sql/
http://codingcraft.ru/sql_queries.php

LinqToSQL and Linq.

Create a project LessonProject.Model to work with the database of type ClassLibrary.
Add LINQ to SQL Classes type, call LessonProejctDb.dbml



Open the object, select all the tables and drag it to the canvas with the mouse:



Actually, with the help of such simple actions we get:


Add some data to the Role and User table:

oneadminAdmin
2customerCustomer


onechernikov@gmail.com1234561/1/2012 12:00:00 AMNull123456NullNull
2chernikov2@gmail.com1234561/1/2012 12:00:00 AMNull123456NullNull


And userole

IDUseridRoleID
oneoneone
2one2
322


Create a console project Lesson3 and connect LessonProject.Model. Add the System.Configuration and System.Data.Linq assembly. Initialize the context and display data about the roles:
  class Program { static void Main(string[] args) { var context = new LessonProjectDbDataContext(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString); var roles = context.Roles.ToList(); foreach (var role in roles) { Console.WriteLine("{0} {1} {2}", role.ID, role.Code, role.Name); } Console.ReadLine(); } } 


To add a line to Role, do this:
 var newRole = new Role { Code = "manager", Name = "" }; context.Roles.InsertOnSubmit(newRole); context.Roles.Context.SubmitChanges(); 

To delete a line in Role, do this:
 var role = context.Roles.Where(p => p.Name == "").FirstOrDefault(); if (role != null) { context.Roles.DeleteOnSubmit(role); context.Roles.Context.SubmitChanges(); } 

To change the data, do this:
 var role = context.Roles.Where(p => p.Name == "").FirstOrDefault(); if (role != null) { role.Name = ""; context.Roles.Context.SubmitChanges(); } 

Linq query language is used to manipulate data. We will cover only some basic Linq functions. Linq is used for types implementing IQueryable interface <>


Note: First(), FirstOrDefault(), Single(), SingleOrDefault(), Any(), Count() - can use the parameter corresponding to Where() , thus, you can reduce the record:
 var roles = context.Roles.FirstOrDefault(p => p.Name == "") 


More examples and uses of linq can be found:
http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b


Creating an IRepository, SqlRepository Repository.


Actually, we can already work with the database, only now we need to separate the data model from the concrete implementation, i.e. Our controllers about context and System.Data.Linq should not know anything at all.

To do this, create an interface IRepository, which will be given access to the data, and also deduced methods for creating, modifying and deleting this data.
  public interface IRepository { IQueryable<Role> Roles { get; } bool CreateRole(Role instance); bool UpdateRole(Role instance); bool RemoveRole(int idRole); … } 


The implementation is called the SqlRepository. Since we don’t want to specifically link to this SqlRepository context, we will add a Ninject module to the LessonProject.Model project:
 Install-Package Ninject 


Create the SqlRepository class:

  public class SqlRepository : IRepository { [Inject] public LessonProjectDbDataContext Db { get; set; } public IQueryable<Role> Roles { get { throw new NotImplementedException(); } } public bool CreateRole(Role instance) { throw new NotImplementedException(); } public bool UpdateRole(Role instance) { throw new NotImplementedException(); } public bool RemoveRole(int idRole) { throw new NotImplementedException(); } } 


Before implementing access to all tables, creation, deletion and modification, we will think that this file will look huge and clumsy. This code will be hard to manage physically. So let's make a separate SqlRepository folder and the SqlRepository class will be partial, and in the folder we will create implementations of the IRepository interface, broken down into each table. Name the file Role:

  public partial class SqlRepository { public IQueryable<Role> Roles { get { return Db.Roles; } } public bool CreateRole(Role instance) { if (instance.ID == 0) { Db.Roles.InsertOnSubmit(instance); Db.Roles.Context.SubmitChanges(); return true; } return false; } public bool RemoveRole(int idRole) { Role instance = Db.Roles.FirstOrDefault(p => p.ID == idRole); if (instance != null) { Db.Roles.DeleteOnSubmit(instance); Db.Roles.Context.SubmitChanges(); return true; } return false; } } 


A small project contains from 10 to 40 tables, a large project from 40, and I would like to automate all this. Create several snippets for the IRepository and for the SqlRepository. Snippets are ready-made code templates that are invoked with intelliSence and allow you to quickly create code.

Snipples


For IRepository tables, create a table.snippet:
 <CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet"> <CodeSnippet Format="1.0.0" > <Header> <Title> Table </Title> <Shortcut>Table</Shortcut> </Header> <Snippet> <Declarations> <Literal> <ID>Table</ID> <ToolTip>Table name for create.</ToolTip> <Default>Table</Default> </Literal> </Declarations> <Code Language="CSharp"> <![CDATA[ #region $Table$ IQueryable<$Table$> $Table$s { get; } bool Create$Table$($Table$ instance); bool Update$Table$($Table$ instance); bool Remove$Table$(int id$Table$); #endregion ]]> </Code> </Snippet> </CodeSnippet> </CodeSnippets> 


For the SqlRepository, create a sqlTable.snippet snippet:
 <CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet"> <CodeSnippet Format="1.0.0" > <Header> <Title> Sql repository </Title> <Shortcut>sqltable</Shortcut> </Header> <Snippet> <Declarations> <Literal> <ID>Table</ID> <ToolTip>Table name for create.</ToolTip> <Default>Table</Default> </Literal> </Declarations> <Code Language="CSharp"> <![CDATA[ public IQueryable<$Table$> $Table$s { get { return Db.$Table$s; } } public bool Create$Table$($Table$ instance) { if (instance.ID == 0) { Db.$Table$s.InsertOnSubmit(instance); Db.$Table$s.Context.SubmitChanges(); return true; } return false; } public bool Update$Table$($Table$ instance) { $Table$ cache = Db.$Table$s.Where(p => p.ID == instance.ID).FirstOrDefault(); if (cache != null) { //TODO : Update fields for $Table$ Db.$Table$s.Context.SubmitChanges(); return true; } return false; } public bool Remove$Table$(int id$Table$) { $Table$ instance = Db.$Table$s.Where(p => p.ID == id$Table$).FirstOrDefault(); if (instance != null) { Db.$Table$s.DeleteOnSubmit(instance); Db.$Table$s.Context.SubmitChanges(); return true; } return false; } ]]> </Code> </Snippet> </CodeSnippet> </CodeSnippets> 

To add a code-snippet. open TOOLS -> Code Snippet Manager ... (Ctrl-K, B). In the window, click Import and import both snippets into My Code snippet:



Finish, OK.
Use for tables User and UserRole.





It remains to register only the fields for Update [table name], but this is less work.

Proxy

As you can see, the classes that we use are partial, so you can add them. Let's create, like SqlRepository, a folder Proxy, where we will allocate partial classes. For example, for the User class, create a method that automatically generates the string required for user activation:
  public partial class User { public static string GetActivateUrl() { return Guid.NewGuid().ToString("N"); } } 

We use this:
 public bool CreateUser(User instance) { if (instance.ID == 0) { instance.AddedDate = DateTime.Now; instance.ActivatedLink = User.GetActivateUrl(); Db.Users.InsertOnSubmit(instance); Db.Users.Context.SubmitChanges(); return true; } return false; } 


Using DB in asp.net mvc

Add the database access string to web.Config:
 <connectionStrings> <add name="ConnectionString" connectionString="Data Source=SATURN-PC;Initial Catalog=LessonProject;Integrated Security=True;Pooling=False" providerName="System.Data.SqlClient" /> </connectionStrings> 

Initialize the work with the database in Ninject:
  private static void RegisterServices(IKernel kernel) { kernel.Bind<LessonProjectDbDataContext>().ToMethod(c => new LessonProjectDbDataContext(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString)); kernel.Bind<IRepository>().To<SqlRepository>().InRequestScope(); } 

Apply InRequestScope (). Those. each query will use a separate SqlRepository object. This will avoid collisions during execution. We declare the IRepository in the controller:
  public class HomeController : Controller { [Inject] public IRepository Repository { get; set; } public ActionResult Index() { var roles = Repository.Roles.ToList(); return View(roles); } } 


And update the View (/Views/Home/Index.cshtml):
 @model IList<LessonProject.Model.Role> @{ ViewBag.Title = "LessonProject"; Layout = "~/Views/Shared/_Layout.cshtml"; } <h2>LessonProject</h2> <p> @foreach (var role in Model) { <div class="item"> <span class="id"> @role.ID </span> <span class="name"> @role.Name </span> <span class="Code"> @role.Code </span> </div> } </p> 


We get a good result:



All sources are located at https://bitbucket.org/chernikov/lessons

Source: https://habr.com/ru/post/176017/


All Articles