ابزار کمکی sql server جهت BI
کتابخانه Timesheet.js
بررسی ()Object.observe در HTML 5
LocalDB چیست؟
EF Code First #12
معرفی سرویسهای ارائه شده توسط شرکتهای گوگل، آمازون و مایکروسافت در قالب رایانش ابری - قسمت دوم
سرویسها و اجزای وب سرویس آمازون:
وب سرویسهای آمازون دارای اجزای زیادی میباشند. تعدادی از این سرویسها برای ارائه خدمات پردازشی و تعداد دیگری برای ارائه فضای ذخیرهسازی، عرضه شدهاند. در ادامه گروهی از این سرویسها معرفی میگردد:
- ابر محاسباتی توسعه پذیر آمازون (EC2)
- سرویس صف ساده آمازون(Simple Queue Service): یک صف پیام یا سیستم تراکنش برای برنامههای مبتنی بر اینترنت توزیع شده میباشد. این سرویس تضمین میکند که پیامها حتی در زمانی که مؤلفهای موجود نیست، گم نشود و برای انتقال پیام میان مؤلفههای مختلف که هرکدام کار جداگانهای را انجام میدهند، بسیار مناسب است.
- سرویس
آگاه سازی ساده آمازون(Simple Notification Service): ): وب سرویسی است که میتواند پیام
یک برنامه را منتشر کند و آنها را به برنامهها یا مشترکین دیگر منتقل کند. SNS متدی
را برای راهاندازی فعالیتها ارائه مینماید که برنامهها را قادر میسازد تا در
مورد اطلاعات جدید یا تغییر یافته از آنها نظرسنجی شود یا به روز رسانیها را
انجام دهند.
- سرویس
نظارت ابر آمازون(Amazon Cloud Watch): کنسولی
را فراهم میکند که در آن مصرف منابع، شاخصهای کلیدی عملکرد سایت و نشانگرهای
عملیاتی برای عواملی همچون تقاضای پردازشگر، مصرف دیسک و ورودی و خروجی شبکه را
ارائه میدهد. نتایج
معیارهایی که توسط آن کسب میشود برای فعالسازی قابلیتی به نام Auto Scaling مورد
استفاده قرار میگیرد که به صورت خودکار میتواند یک سایت EC2 را بر مبنای مجموعهای از قوانین
که توسعه دهنده ایجاد میکند، توسعه دهد.
- توازن بار منعطف(Elastic Load Balancing): نمونههای ماشین آمازون(Amazon Machine Image) با استفاده از این قابلیت، دارای امکان توازن بار ترافیکی میشوند. این قابلیت هنگامی که نمونهای دچار شکست میشود آن را کشف کرده و ترافیک را به یک نمونه سالم حتی نمونهای در محیطهای دیگر AWS مسیریابی مجدد میکند.
قیمت گذاری انواع مختلف نمونه ماشین آمازون به سه پارامتر وابسته است. اولین مورد سیستم عامل مورد استفاده است. دومین عامل مرکز دادهای است که در آن قرار گرفته و سومین عامل مدت زمانی است که اجرا میشود. نرخها بر مبنای ساعت محاسبه میشوند. علاوه بر آن مبالغ اضافی نیز بابت موارد زیر اخذ میشود:
- میزان داده
منتقل شده
- آدرسهای IP اختصاصی
- استفاده
سرور اختصاصی مجازی از فضای ذخیرهسازی بلوکی توسعه پذیر آمازون
- استفاده از توازن بار توسعه پذیر برای دو یا چند سرور
- سایر
ویژگیهای مورد نیاز
- نمونه
مبتنی بر تقاضا: نرخ
ساعتی بدون التزام طولانی مدت
-
نمونه رزرو شده: خرید قراردادی هر نمونه با هزینه به مراتب پایینتر به ازای هر ساعت بعد از رزرو اولیه
-
نمونه نقطهای: این متد برای قیمت گذاری بر روی ظرفیت استفاده نشده EC2 بر مبنای قیمت نقطه فعلی است. این قابلیت، قیمتهای بسیار پایین را به همراه خواهد داشت اما در زمانهای مختلف فرق میکند یا در زمانی که ظرفیت مازادی نباشد، در دسترس نخواهد بود.
نوع | موتور محاسبه | حافظه اصلی(GB) | ذخیره سازی(GB) | سکو |
ریز نمونه | تا دو واحد محاسباتی در انفجار بار | 0.613 | EBS | 32 یا 64 بیتی |
نمونه کوچک | یک واحد محاسباتی | 1.7 | 160 | 32 بیتی |
نمونه بزرگ | چهار واحد محاسباتی | 7.5 | 850 | 64 بیتی |
نمونه بسیار بزرگ | هشت واحد محاسباتی | 15 | 1690 | 64 بیتی |
نیاز به درایور OleDB مخصوص بانکهای اطلاعاتی قدیمی
برای کار با بانکهای اطلاعاتی قدیمی از طریق ADO.NET، نیاز است بتوان به نحوی با آنها ارتباط برقرار کرد و اینکار از طریق استاندارد OleDB که صرفا مختص به ویندوز است، قابل انجام است. برای مثال برای کار با فاکسپرو نیز در ابتدا باید درایور OleDB آنرا نصب کرد که ... هیچکدام از لینکهای قدیمی مایکروسافت در این زمینه دیگر وجود خارجی ندارند! آخرین نگارش مرتبط را میتوانید در این آدرس و ذیل نام VFPOLEDBSetup.msi دریافت کنید (نگارش 9 را نصب میکند).
نیاز به دریافت بستهی System.Data.OleDb
در اولین قدم جهت کار با درایور OleDB نصب شده، باید یک اتصال را توسط نمونه سازی شیء OleDbConnection ایجاد کرد که ... این شیء هم شناسایی نمیشود. به همین جهت باید بستهی نیوگت مرتبط با آنرا به صورت جداگانهای دریافت و نصب کرد:
<ItemGroup> <PackageReference Include="System.Data.OleDb" Version="7.0.0"/> </ItemGroup>
برنامهی مبتنی بر درایور OleDB فاکسپرو اجرا نمیشود!
اولین سعی در برقراری ارتباط با درایور OleDB نصب شده، با خطای زیر خاتمه مییابد:
The 'VFPOLEDB' provider is not registered on the local machine.
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <PlatformTarget>x86</PlatformTarget> </PropertyGroup>
روش یافتن نام پروایدر OleDB نصب شده
رشتههای اتصالی OleDB، با =Provider، شروع میشوند. اکنون این سؤال مطرح میشود که پس از نصب VFPOLEDBSetup.ms یاد شده، دقیقا چه پروایدری به سیستم اضافه شدهاست و نام آن چیست؟
برای اینکار میتوان از چندسطر زیر برای یافتن نام تمام پروایدرهای OleDB نصب شدهی بر روی سیستم استفاده کرد:
var oleDbEnumerator = new OleDbEnumerator(); using var elements = oleDbEnumerator.GetElements(); foreach (DataRow row in elements.Rows) { Console.WriteLine($"{row["SOURCES_DESCRIPTION"]}: {row["SOURCES_NAME"]}"); }
Microsoft OLE DB Provider for SQL Server: SQLOLEDB MSDataShape: MSDataShape SQL Server Native Client 11.0: SQLNCLI11 Microsoft OLE DB Provider for Visual FoxPro: VFPOLEDB OLE DB Provider for Microsoft Directory Services: ADsDSOObject Microsoft OLE DB Driver for SQL Server: MSOLEDBSQL Microsoft OLE DB Driver for SQL Server Enumerator: MSOLEDBSQL Enumerator SQL Server Native Client 11.0 Enumerator: SQLNCLI11 Enumerator Microsoft OLE DB Provider for Search: Windows Search Data Source Microsoft OLE DB Provider for ODBC Drivers: MSDASQL Microsoft OLE DB Enumerator for ODBC Drivers: MSDASQL Enumerator Microsoft OLE DB Provider for Analysis Services 14.0: MSOLAP Microsoft OLE DB Provider for Analysis Services 14.0: MSOLAP Microsoft Jet 4.0 OLE DB Provider: Microsoft.Jet.OLEDB.4.0 Microsoft OLE DB Enumerator for SQL Server: SQLOLEDB Enumerator Microsoft OLE DB Simple Provider: MSDAOSP Microsoft OLE DB Provider for Oracle: MSDAORA
Microsoft OLE DB Provider for Visual FoxPro: VFPOLEDB
روش خواندن اطلاعات یک بانک اطلاعاتی فاکس پرو
پس از این مقدمات و تنظیمات، اکنون میتوانیم از قطعه کد متداول ADO.NET زیر، جهت خواندن اطلاعات یک بانک اطلاعاتی فاکسپرو، استفاده کنیم:
var connectionString = "Provider=VFPOLEDB;Data Source=" + @"C:\path\Db.DBF;Password=;Collating Sequence=MACHINE"; using var dbConnection = new OleDbConnection(connectionString); using var dataAdapter = new OleDbDataAdapter("select family from Db.DBF", dbConnection); using var dataset = new DataSet(); dataAdapter.Fill(dataset, "table1"); var sb = new StringBuilder(); foreach (DataRow dataRow in dataset.Tables[0].Rows) { var iranSystem = dataRow[0] as string; var unicode = iranSystem.FromIranSystemToUnicode(); if (!string.IsNullOrWhiteSpace(unicode)) { sb.AppendLine($"[DataRow(\"{iranSystem}\", \"{unicode}\")]"); } }
- نام پروایدر در رشته اتصالی، به VFPOLEDB تنظیم شدهاست.
- select انجام شده بر روی نام فایل dbf انجام میشود. یعنی هر فایل dbf، یک جدول را تشکیل میدهد.
- اگر نام فیلدهای موجود را نمیدانید، بجای select family از * select استفاده کنید و سپس بر روی DataSet پر شده، یک break-point را قرار دهید تا بتوانید نام تمام ستونها را از آن استخراج کنید.
- رشتهای را که توسط درایور فاکسپرو دریافت میکنید، یک رشتهی اسکی سیستم عامل داس است که در دات نت، با encoding مساوی 1252 شناخته میشود. یعنی encoding این رشتهی دریافتی، یونیکد پیشفرض داتنت نیست و باید توسط متد Encoding.GetEncoding(1252).GetBytes پردازش شود. که در نگارشهای جدید دات نت، این کدپیجها به صورت پیشفرض مهیا نیستند و باید در ابتدا ثبت شوند تا قابل استفاده شوند:
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance)
ایجاد یک برنامهی Minimal-API جدید در دات نت 8
پروژهای را که در اینجا پیگیری میکنیم، بر اساس قالب استاندارد تولید شدهی توسط دستور dotnet new webapi تکمیل میشود.
ایجاد یک صفحهی Blazor 8x به همراه مسیریابی و دریافت پارامتر
در ادامه قصد داریم که یک کامپوننت جدید را به نام SsrTest.razor در پوشهی جدید Components\Tests ایجاد کرده و برای آن مسیریابی از نوع page@ هم تعریف کنیم. یعنی نهفقط قصد داریم آنرا توسط RazorComponentResult رندر کنیم، بلکه میخواهیم اگر آدرس آنرا در مرورگر هم وارد کردیم، قابل دسترسی باشد.
به همین جهت یک پوشهی جدید را به نام Components در ریشهی پروژهی Web API جاری ایجاد میکنیم، با این محتوا:
برای ایده گرفتن از محتوای مورد نیاز، به «معرفی قالبهای جدید شروع پروژههای Blazor در دات نت 8» قسمت دوم این سری مراجعه کرده و برای مثال قالب سادهترین حالت ممکن را توسط دستور زیر تولید میکنیم (در یک پروژهی مجزا، خارج از پروژهی جاری):
dotnet new blazor --interactivity None
- فایل Imports.razor_ ساده شده برای سهولت کار با فضاهای نام در کامپوننتهای Blazor (فضاهای نامی را که در آن وجود ندارند و مرتبط با پروژهی دوم هستند، حذف میکنیم).
- فایل App.razor، برای تشکیل نقطهی آغازین برنامهی Blazor.
- فایل Routes.razor برای معرفی مسیریابی صفحات Blazor تعریف شده.
- پوشهی Layout برای معرفی فایل MainLayout.razor که در Routes.razor استفاده شدهاست.
و ... یک فایل آزمایشی جدید به نام Components\Tests\SsrTest.razor با محتوای زیر:
@page "/ssr-page/{Data:int}" <PageTitle>An SSR component</PageTitle> <h1>An SSR component rendered by a Minimal-API!</h1> <div> Data: @Data </div> @code { [Parameter] public int Data { get; set; } }
تغییرات مورد نیاز در فایل Program.cs برنامهی Web-API برای فعالسازی رندر سمت سرور Blazor
در ادامه کل تغییرات مورد نیاز جهت اجرای این برنامه را مشاهده میکنید:
var builder = WebApplication.CreateBuilder(args); // ... builder.Services.AddRazorComponents(); // ... // http://localhost:5227/ssr-component?data=2 // or it can be called directly http://localhost:5227/ssr-page/2 app.MapGet("/ssr-component", (int data = 1) => { var parameters = new Dictionary<string, object?> { { nameof(SsrTest.Data), data }, }; return new RazorComponentResult<SsrTest>(parameters); }); app.UseStaticFiles(); app.UseAntiforgery(); app.MapRazorComponents<App>(); app.Run(); // ...
- همین اندازه تغییر در جهت فعالسازی رندر سمت سرور کامپوننتهای Blazor در یک برنامهی ASP.NET Core کفایت میکند. یعنی اضافه شدن:
AddRazorComponents ،UseAntiforgery و MapRazorComponents
- در اینجا نحوهی ارسال پارامترها را به یک RazorComponentResult نیز مشاهده میکنید.
- در حالت فراخوانی از طریق مسیر endpoint (یعنی فراخوانی مسیر http://localhost:5227/ssr-component در مثال فوق)، خود کامپوننت فراخوانی شده، بدون layout تعریف شدهی در فایل App.razor، رندر میشود. علت اینجا است که layout برنامه به همراه کامپوننت Router و RouteView آن فعال میشود که این دو هم مختص به صفحات دارای مسیریابی Blazor هستند و برای رندر کامپوننتهای خالص آن بکار گرفته نمیشوند. خروجی RazorComponentResult تنها یک static SSR خالص است؛ مگر اینکه فایل blazor.web.js را نیز بارگذاری کند.
یک نکته: اگر در حالت رندر توسط RazorComponentResult، علاقمند به استفادهی از layout هستید، میتوان از کامپوننت LayoutView داخل یک کامپوننت فرضی به صورت زیر استفاده کرد؛ اما این مورد هم شامل اطلاعات فایل App.razor نمیشود:
<LayoutView Layout="@typeof(MainLayout)"> <PageTitle>Home</PageTitle> <h2>Welcome to your new app.</h2> </LayoutView>
سؤال: آیا در این حالت کامپوننتهای تعاملی هم کار میکنند؟
پاسخ: بله. فقط برای ایده گرفتن، یک نمونه پروژهی تعاملی Blazor 8x را در ابتدا ایجاد کنید و قسمتهای اضافی AddRazorComponents و MapRazorComponents آنرا در اینجا کپی کنید؛ یعنی برای مثال جهت فعالسازی کامپوننتهای تعاملی Blazor Server، به این دو تغییر زیر نیاز است:
// ... builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); // ... app.MapRazorComponents<App>().AddInteractiveServerRenderMode(); // ...
<script src="_framework/blazor.web.js"></script>
@rendermode InteractiveServer <h1>Counter</h1> <p role="status">Current count: @_currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> @code { private int _currentCount; private void IncrementCount() { _currentCount++; } }
// http://localhost:5227/server-interactive-component app.MapGet("/server-interactive-component", () => new RazorComponentResult<Counter>());
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Interactive server component</title> <base href="/"/> </head> <body> <h1>Interactive server component</h1> <Counter/> <script src="_framework/blazor.web.js"></script> </body> </html>
سپس تعریف endpoint متناظر را به صورت زیر تغییر میدهیم:
// http://localhost:5227/server-interactive-component app.MapGet("/server-interactive-component", () => new RazorComponentResult<CounterInteractive>());
سؤال: آیا میتوان این خروجی static SSR کامپوننتهای بلیزر را در سرویسهای یک برنامه ASP.NET Core هم دریافت کرد؟
منظور این است که آیا میتوان از یک کامپوننت Blazor، به همراه تمام پیشرفتهای Razor در آن که در Viewهای MVC قابل دسترسی نیستند، بهشکل یک رشتهی خالص، خروجی گرفت و برای مثال از آن بهعنوان قالب پویای محتوای ایمیلها استفاده کرد؟
پاسخ: بله! زیر ساخت RazorComponentResult که از سرویس HtmlRenderer استفاده میکند، بدون نیاز به برپایی یک endpoint هم قابل دسترسی است:
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; namespace WebApi8x.Services; public class BlazorStaticRendererService { private readonly HtmlRenderer _htmlRenderer; public BlazorStaticRendererService(HtmlRenderer htmlRenderer) => _htmlRenderer = htmlRenderer; public Task<string> StaticRenderComponentAsync<T>() where T : IComponent => RenderComponentAsync<T>(ParameterView.Empty); public Task<string> StaticRenderComponentAsync<T>(Dictionary<string, object?> dictionary) where T : IComponent => RenderComponentAsync<T>(ParameterView.FromDictionary(dictionary)); private Task<string> RenderComponentAsync<T>(ParameterView parameters) where T : IComponent => _htmlRenderer.Dispatcher.InvokeAsync(async () => { var output = await _htmlRenderer.RenderComponentAsync<T>(parameters); return output.ToHtmlString(); }); }
builder.Services.AddScoped<HtmlRenderer>(); builder.Services.AddScoped<BlazorStaticRendererService>();
app.MapGet("/static-renderer-service-test", async (BlazorStaticRendererService renderer, int data = 1) => { var parameters = new Dictionary<string, object?> { { nameof(SsrTest.Data), data }, }; var html = await renderer.StaticRenderComponentAsync<SsrTest>(parameters); return Results.Content(html, "text/html"); });
کدهای کامل این مطلب را میتوانید از اینجا دریافت کنید: WebApi8x.zip