معرفی
Cloud SQL یک سرویس پایگاه داده کاملاً مدیریت شده است که ردیف کردن، نگهداری، مدیریت و مدیریت پایگاههای اطلاعاتی PostgreSQL و MySQL را در فضای ابری ساده میکند. Cloud SQL عملکرد، مقیاس پذیری و راحتی بالایی را ارائه می دهد. Cloud SQL که بر روی پلتفرم Google Cloud میزبانی می شود، زیرساخت داده را برای برنامه هایی که در هر مکانی اجرا می شوند فراهم می کند.
درباره Blazor Framework
Blazor یک چارچوب وب دات نت از مایکروسافت با استفاده از C#/Razor و HTML است که در مرورگر با Web Assembly اجرا می شود. Blazor تمام مزایای یک چارچوب وب UI سمت سرویس گیرنده را با استفاده از دات نت در مشتری و به صورت اختیاری در سرور ارائه می دهد.
- برنامه تک صفحه ای با Blazor و CosmosDB
- Blazor - CRUD با استفاده از PostgreSQL و Entity Framework Core
- Blazor - با آمازون DynamoDB با استفاده از AWS SDK متصل شوید
- Blazor - کار با Cassandra API در Cosmos DB
- محلی سازی در برنامه Blazor با استفاده از Microsoft.JSInterop
- Blazor - ایجاد SPA با پایگاه داده Azure برای سرور MariaDB
- Blazor - با پایگاه داده اوراکل در آمازون RDS ارتباط برقرار کنید
- فیدهای RSS Corner C# را در پروژه Blazor دریافت کنید
- C# Corner RSS در Blazor با صفحهبندی فید میشود
- با استفاده از Elastic Beanstalk، برنامه Blazor را در AWS Cloud اجرا کنید
- کش Azure Redis با Azure SQL در پروژه Blazor
- برنامه تک صفحه ای در Blazor با ذخیره سازی جدول Azure
- یک نمودار ساده بر اساس تاریخ برای آخرین تعداد مقالات گوشه C# ایجاد کنید
- اشکال زدایی برنامه Blazor از راه دور در Azure از ویژوال استودیو
نمونه Google Cloud SQL را با موتور MySQL ایجاد کنید
قبل از راه اندازی باید یک حساب Google Cloud ایجاد کنید. در حال حاضر، گوگل یک عضویت رایگان یک ساله با اعتبار 300 دلاری ارائه می دهد.
با اطلاعات کاربری Google خود وارد Google Cloud c onsole شوید.
لطفاً اگر پروژه ای دارید انتخاب کنید. در غیر این صورت، میتوانید روی دکمه «پروژه جدید» کلیک کنید تا یک پروژه جدید ایجاد کنید.
![با استفاده از موتور MySQL یک برنامه Blazor با Google Cloud SQL ایجاد کنید](http://pezhvak24.ir/dl/10kcor/cscd/article/create-a-blazor-app-with-google-cloud-sql-using-mysql-engine/Images/01%20New%20Project%20Creation.png)
![با استفاده از موتور MySQL یک برنامه Blazor با Google Cloud SQL ایجاد کنید](http://pezhvak24.ir/dl/10kcor/cscd/article/create-a-blazor-app-with-google-cloud-sql-using-mysql-engine/Images/04%20Choose%20SQL.png)
برای ادامه روی دکمه «ایجاد نمونه» کلیک کنید.
![با استفاده از موتور MySQL یک برنامه Blazor با Google Cloud SQL ایجاد کنید](http://pezhvak24.ir/dl/10kcor/cscd/article/create-a-blazor-app-with-google-cloud-sql-using-mysql-engine/Images/07%20Give%20Instance%20details.png)
اتصال ما در حال حاضر موفقیت آمیز است.
- CREATE DATABASE sarathcloudsql;
- USE sarathcloudsql;
- DROP TABLE IF EXISTS Book;
- CREATE TABLE Book
- (Id VARCHAR(50) PRIMARY KEY,
- Name VARCHAR(50),
- ISBN VARCHAR(50),
- Author VARCHAR(50),
- Price DECIMAL(18,8));
یک پروژه Blazor در ویژوال استودیو 2017 ایجاد کنید
در این مقاله ما یک اپلیکیشن تک صفحه ای Book Data Entry ایجاد می کنیم. من از نسخه رایگان Visual Studio 2017 Community برای ایجاد برنامه Blazor استفاده می کنم .
راه حل ما در عرض چند دقیقه آماده خواهد شد. لطفاً توجه داشته باشید که سه پروژه در راه حل ایجاد شده است - "Client" ، "Server" و "Shared".
به طور پیش فرض، Blazor چند فایل در این سه پروژه ایجاد کرد. میتوانیم تمام فایلهای ناخواسته مانند « Counter.cshtml »، « FetchData.cshtml »، « SurveyPrompt.cshtml » را از پروژه Client و فایل « SampleDataController.cs » را از پروژه سرور حذف کنیم و فایل « WeatherForecast.cs » را از اشتراکگذاری شده حذف کنیم. پروژه نیز
حال، اجازه دهید یک پوشه “ Models ” در پروژه “Shared” ایجاد کنیم و کلاس “Book” را در داخل آن ایجاد کنیم.
- namespace BlazorCloudSQL.Shared.Models
- {
- public class Book
- {
- public string Id
- {
- get;
- set;
- }
- public string Name
- {
- get;
- set;
- }
- public string ISBN
- {
- get;
- set;
- }
- public string Author
- {
- get;
- set;
- }
- public decimal Price
- {
- get;
- set;
- }
- }
- }
بسته NuGet " MySql.Data " را در پروژه "Server" نصب کنید. این بسته توسط شرکت Oracle توسعه یافته است.
- using BlazorCloudSQL.Shared.Models;
- using MySql.Data.MySqlClient;
- using System;
- using System.Collections.Generic;
- using System.Data;
- using System.Threading.Tasks;
- namespace BlazorCloudSQL.Server.DataAccess
- {
- public class CloudSQLContext
- {
- public string ConnectionString { get; set; }
- public CloudSQLContext(string connectionString)
- {
- ConnectionString = connectionString;
- }
- private MySqlConnection GetConnection()
- {
- return new MySqlConnection(ConnectionString);
- }
- public async Task<List<Book>> GetAllAsync()
- {
- List<Book> list = new List<Book>();
- using (MySqlConnection conn = GetConnection())
- {
- conn.Open();
- var commandText = @"SELECT Id,Name,ISBN,Author,Price FROM Book;";
- MySqlCommand cmd = new MySqlCommand(commandText, conn);
- using (var reader = cmd.ExecuteReader())
- {
- while (await reader.ReadAsync())
- {
- list.Add(new Book()
- {
- Id = await reader.GetFieldValueAsync<string>(0),
- Name = await reader.GetFieldValueAsync<string>(1),
- ISBN = await reader.GetFieldValueAsync<string>(2),
- Author = await reader.GetFieldValueAsync<string>(3),
- Price = await reader.GetFieldValueAsync<decimal>(4),
- });
- }
- }
- }
- return list;
- }
- public async Task InsertAsync(Book book)
- {
- book.Id = Guid.NewGuid().ToString();
- using (MySqlConnection conn = GetConnection())
- {
- conn.Open();
- var commandText = @"INSERT INTO Book (Id,Name,ISBN,Author,Price) VALUES (@Id, @Name, @ISBN, @Author, @Price);";
- MySqlCommand cmd = new MySqlCommand(commandText, conn);
- cmd.Parameters.Add(new MySqlParameter
- {
- ParameterName = "@Id",
- DbType = DbType.String,
- Value = book.Id,
- });
- cmd.Parameters.Add(new MySqlParameter
- {
- ParameterName = "@Name",
- DbType = DbType.String,
- Value = book.Name,
- });
- cmd.Parameters.Add(new MySqlParameter
- {
- ParameterName = "@ISBN",
- DbType = DbType.String,
- Value = book.ISBN,
- });
- cmd.Parameters.Add(new MySqlParameter
- {
- ParameterName = "@Author",
- DbType = DbType.String,
- Value = book.Author,
- });
- cmd.Parameters.Add(new MySqlParameter
- {
- ParameterName = "@Price",
- DbType = DbType.Decimal,
- Value = book.Price,
- });
- await cmd.ExecuteNonQueryAsync();
- }
- }
- public async Task UpdateAsync(Book book)
- {
- using (MySqlConnection conn = GetConnection())
- {
- conn.Open();
- var commandText = @"UPDATE Book SET Name=@Name, ISBN=@ISBN, Author=@Author, Price=@Price Where Id=@Id;";
- MySqlCommand cmd = new MySqlCommand(commandText, conn);
- cmd.Parameters.Add(new MySqlParameter
- {
- ParameterName = "@Id",
- DbType = DbType.String,
- Value = book.Id,
- });
- cmd.Parameters.Add(new MySqlParameter
- {
- ParameterName = "@Name",
- DbType = DbType.String,
- Value = book.Name,
- });
- cmd.Parameters.Add(new MySqlParameter
- {
- ParameterName = "@ISBN",
- DbType = DbType.String,
- Value = book.ISBN,
- });
- cmd.Parameters.Add(new MySqlParameter
- {
- ParameterName = "@Author",
- DbType = DbType.String,
- Value = book.Author,
- });
- cmd.Parameters.Add(new MySqlParameter
- {
- ParameterName = "@Price",
- DbType = DbType.Decimal,
- Value = book.Price,
- });
- await cmd.ExecuteNonQueryAsync();
- }
- }
- public async Task DeleteAsync(string id)
- {
- using (MySqlConnection conn = GetConnection())
- {
- conn.Open();
- var commandText = @"DELETE FROM Book Where Id=@Id;";
- MySqlCommand cmd = new MySqlCommand(commandText, conn);
- cmd.Parameters.Add(new MySqlParameter
- {
- ParameterName = "@Id",
- DbType = DbType.String,
- Value = id,
- });
- await cmd.ExecuteNonQueryAsync();
- }
- }
- public async Task<Book> FindOneAsync(string id)
- {
- using (MySqlConnection conn = GetConnection())
- {
- conn.Open();
- var commandText = @"SELECT Name,ISBN,Author,Price FROM Book Where Id=@Id;";
- MySqlCommand cmd = new MySqlCommand(commandText, conn);
- cmd.Parameters.Add(new MySqlParameter
- {
- ParameterName = "@Id",
- DbType = DbType.String,
- Value = id,
- });
- using (var reader = cmd.ExecuteReader())
- {
- if (await reader.ReadAsync())
- {
- return new Book()
- {
- Id = id,
- Name = await reader.GetFieldValueAsync<string>(0),
- ISBN = await reader.GetFieldValueAsync<string>(1),
- Author = await reader.GetFieldValueAsync<string>(2),
- Price = await reader.GetFieldValueAsync<decimal>(3),
- };
- }
- else
- {
- return null;
- }
- }
- }
- }
- }
- }
ما هر متد را برای اقدامات CRUD در داخل این کلاس ایجاد کرده ایم. لطفاً توجه داشته باشید که ما از کلاس " MySqlConnection " از کتابخانه "MySql.Data" برای اتصال پایگاه داده MySQL استفاده می کنیم.
- using BlazorCloudSQL.Server.DataAccess;
- using Microsoft.AspNetCore.Blazor.Server;
- using Microsoft.AspNetCore.Builder;
- using Microsoft.AspNetCore.Hosting;
- using Microsoft.AspNetCore.ResponseCompression;
- using Microsoft.Extensions.DependencyInjection;
- using System.Linq;
- using System.Net.Mime;
- namespace BlazorCloudSQL.Server
- {
- public class Startup
- {
- public void ConfigureServices(IServiceCollection services)
- {
- services.AddMvc();
- services.AddResponseCompression(options =>
- {
- options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(new[]
- {
- MediaTypeNames.Application.Octet,
- WasmMediaTypeNames.Application.Wasm,
- });
- });
- var connStr = "Server=<Your Server IP>; Port=3306; Database=sarathcloudsql; Uid=root; Pwd=<Your Password>; SslMode=Preferred;";
- services.Add(new ServiceDescriptor(typeof(CloudSQLContext), new CloudSQLContext(connStr)));
- }
- public void Configure(IApplicationBuilder app, IHostingEnvironment env)
- {
- app.UseResponseCompression();
- if (env.IsDevelopment())
- {
- app.UseDeveloperExceptionPage();
- }
- app.UseMvc(routes =>
- {
- routes.MapRoute(name: "default", template: "{controller}/{action}/{id?}");
- });
- app.UseBlazor<Client.Program>();
- }
- }
- }
برای سادگی، من جزئیات اتصال MySQL را در کلاس Startup با سیم سخت نصب کرده ام. حتی می توانید در صورت نیاز این جزئیات اتصال را در یک فایل پیکربندی جداگانه نگهداری کنید.
اکنون می توانیم Books Controller را ایجاد کنیم. لطفا کد زیر را به این کلاس Controller اضافه کنید.
- using BlazorCloudSQL.Server.DataAccess;
- using BlazorCloudSQL.Shared.Models;
- using Microsoft.AspNetCore.Mvc;
- using System.Collections.Generic;
- using System.Threading.Tasks;
- namespace BlazorCloudSQL.Server.Controllers
- {
- [Route("api/[controller]")]
- public class BooksController : Controller
- {
- [HttpGet]
- public async Task<IEnumerable<Book>> GetAsync()
- {
- CloudSQLContext context = HttpContext.RequestServices.GetService(typeof(CloudSQLContext)) as CloudSQLContext;
- return await context.GetAllAsync();
- }
- [HttpGet("{id}")]
- public async Task<Book> Get(string id)
- {
- CloudSQLContext context = HttpContext.RequestServices.GetService(typeof(CloudSQLContext)) as CloudSQLContext;
- return await context.FindOneAsync(id);
- }
- [HttpPost]
- public async Task Post([FromBody] Book book)
- {
- if (ModelState.IsValid)
- {
- CloudSQLContext context = HttpContext.RequestServices.GetService(typeof(CloudSQLContext)) as CloudSQLContext;
- await context.InsertAsync(book);
- }
- }
- [HttpPut]
- public async Task Put([FromBody] Book book)
- {
- if (ModelState.IsValid)
- {
- CloudSQLContext context = HttpContext.RequestServices.GetService(typeof(CloudSQLContext)) as CloudSQLContext;
- await context.UpdateAsync(book);
- }
- }
- [HttpDelete("{id}")]
- public async Task Delete(string id)
- {
- CloudSQLContext context = HttpContext.RequestServices.GetService(typeof(CloudSQLContext)) as CloudSQLContext;
- await context.DeleteAsync(id);
- }
- }
- }
ما تمام عملیات CRUD را در این کنترلر اضافه کرده ایم. در اینجا متدهایی را از کلاس CloudSQLContext فراخوانی خواهیم کرد .
به پروژه "Client" بروید و " NavMenu" را تغییر دهید . cshtml ” Razor View در داخل پوشه “Shared”.
- <div class="top-row pl-4 navbar navbar-dark">
- <a class="navbar-brand" href="">Blazor Cloud SQL App</a>
- <button class="navbar-toggler" onclick=@ToggleNavMenu>
- <span class="navbar-toggler-icon"></span>
- </button>
- </div>
- <div class=@(collapseNavMenu ? "collapse" : null) onclick=@ToggleNavMenu>
- <ul class="nav flex-column">
- <li class="nav-item px-3">
- <NavLink class="nav-link" href="" Match=NavLinkMatch.All>
- <span class="oi oi-home" aria-hidden="true"></span> Home
- </NavLink>
- </li>
- <li class="nav-item px-3">
- <NavLink class="nav-link" href="/listbooks">
- <span class="oi oi-plus" aria-hidden="true"></span> Book Details
- </NavLink>
- </li>
- </ul>
- </div>
- @functions {
- bool collapseNavMenu = true;
- void ToggleNavMenu()
- {
- collapseNavMenu = !collapseNavMenu;
- }
- }
ما می توانیم یک Razor View جدید در پوشه "Pages" برای لیست کردن تمام جزئیات کتاب ایجاد کنیم. کد زیر را به Razor View اضافه کنید.
- @using BlazorCloudSQL.Shared.Models
- @page "/listbooks"
- @inject HttpClient Http
- <h4>Book Details</h4>
- <p>
- <a href="/addbook">Create New Book</a>
- </p>
- @if (books == null)
- {
- <p><em>Loading...</em></p>
- }
- else
- {
- <table class='table'>
- <thead>
- <tr>
- <th>Name</th>
- <th>ISBN</th>
- <th>Author</th>
- <th>Price</th>
- </tr>
- </thead>
- <tbody>
- @foreach (var book in books)
- {
- <tr>
- <td>@book.Name</td>
- <td>@book.ISBN</td>
- <td>@book.Author</td>
- <td>@book.Price</td>
- <td>
- <a href='/editbook/@book.Id'>Edit</a>
- <a href='/deletebook/@book.Id'>Delete</a>
- </td>
- </tr>
- }
- </tbody>
- </table>
- }
- @functions {
- Book[] books;
- protected override async Task OnInitAsync()
- {
- books = await Http.GetJsonAsync<Book[]>("/api/books");
- }
- }
بیایید سه فایل دیگر Razor View اضافه کنیم و کدهای زیر را اضافه کنیم.
- @using BlazorCloudSQL.Shared.Models
- @page "/addbook"
- @inject HttpClient Http
- @inject Microsoft.AspNetCore.Blazor.Services.IUriHelper UriHelper
- <h4>Create Book</h4>
- <hr />
- <form>
- <div class="row">
- <div class="col-md-8">
- <div class="form-group">
- <label for="Name" class="control-label">Name</label>
- <input for="Name" class="form-control" bind="@book.Name" />
- </div>
- <div class="form-group">
- <label for="ISBN" class="control-label">ISBN</label>
- <input for="ISBN" class="form-control" bind="@book.ISBN" />
- </div>
- <div class="form-group">
- <label for="Author" class="control-label">Author</label>
- <input for="Author" class="form-control" bind="@book.Author" />
- </div>
- <div class="form-group">
- <label for="Price" class="control-label">Price</label>
- <input for="Price" class="form-control" bind="@book.Price" />
- </div>
- </div>
- </div>
- <div class="row">
- <div class="col-md-4">
- <div class="form-group">
- <input type="button" class="btn btn-default" onclick="@(async () => await CreateBook())" value="Save" />
- <input type="button" class="btn" onclick="@Cancel" value="Cancel" />
- </div>
- </div>
- </div>
- </form>
- @functions {
- Book book = new Book();
- protected async Task CreateBook()
- {
- await Http.SendJsonAsync(HttpMethod.Post, "/api/books", book);
- UriHelper.NavigateTo("/listbooks");
- }
- void Cancel()
- {
- UriHelper.NavigateTo("/listbooks");
- }
- }