اشتراکها
اشتراکها
راهنمای طراحی PPM
در قسمت قبل، ساختار ابتدایی یک پروژهی Minimal API's مبتنی بر معماری Vertical slices را تشکیل دادیم. در ادامه موجودیتها و DbContext آنرا تشکیل میدهیم.
ایجاد مدلها و موجودیتهای برنامهی Minimal Blog
در مثال این سری، هر نویسنده میتواند بلاگ خاص خودش را داشته باشد و در هر بلاگ، تعدادی مقاله منتشر کند. هر مقاله هم میتواند تعدادی تگ یا گروه مرتبط را داشته باشد.
ساختار ابتدایی موجودیت نویسندگان مطالب بلاگ
این موجودیتها در پوشهی جدیدی به نام Model پروژهی MinimalBlog.Domain اضافه خواهند شد:
در اینجا تعاریفی مانند !default را هم مشاهده میکنید که مرتبط است با فعال بودن nullable reference types در این پروژه که در فایل Directory.Build.props به صورت سراسری به تمام پروژهها اعمال میشود. با تعریف !default به کامپایلر اعلام میکنیم که این خواص هیچگاه نال نخواهند بود. هدف اصلی از nullable reference types، بالا بردن قابلیت پیش بینی نال بودن، یا نبودن آنها است؛ تا برنامه نویس در قسمتهای مختلف برنامه بداند که آیا واقعال نیاز است هنگام کار با خاصیت FirstName، نال بودن آنرا پیش از استفاده بررسی کند یا خیر؟
ساختار ابتدایی موجودیت مقالات بلاگ
ساختار ابتدایی بلاگهای اختصاصی قابل تعریف
ساختار ابتدایی گروههای مقالات بلاگ
معرفی موجودیتهای تعریف شده به لایهی Dal
لایهی Dal جایی است که DbContext برنامه تعریف میشود و موجودیتها فوق توسط DbSetها در معرض دید EF-Core قرار میگیرند. به همین جهت ابتدا فایل MinimalBlog.Dal.csproj را به صورت زیر تغییر میدهیم:
در اینجا در ابتدا ارجاعی به پروژهی MinimalBlog.Domain.csproj اضافه شدهاست. سپس بستههای مورد نیاز از EF-Core نیز جهت تعریف DbSetها و اجرای Migrations، اضافه شدهاند.
به علاوه تعاریفی مانند ImplicitUsings و Nullable را هم مشاهده میکنید که با توجه به استفادهی از فایل Directory.Build.props غیرضروری و تکراری هستند؛ چون این فایل مخصوص به همراه این تعاریف سراسری نیز هست.
سپس به پروژهی Dal، کلاس جدید MinimalBlogDbContext را به صورت زیر اضافه میکنیم تا مدلهای برنامه را در معرض دید EF-Core قرار دهد:
در اینجا نیز تعاریف !default را مشاهده میکنید که خاصیت راهنمای کامپایلر را در حالت فعال بودن <Nullable>enable</Nullable> دارند و هدف از آن، اعلام نال نبودن این خواص، در حین استفادهی از آنها در قسمتهای مختلف برنامه است.
ایجاد و اجرای Migrations
پس از تعریف MinimalBlogDbContext، اکنون نوبت به ایجاد کلاسهای Migrations و اجرای آنها جهت ایجاد بانک اطلاعاتی متناظر با مدلهای برنامه است. برای این منظور در ابتدا به پروژهی Api مراجعه کرده و فایل appsettings.json را به صورت زیر تکمیل میکنیم:
در اینجا یک رشتهی اتصالی جدید را از نوع SQL Server LocalDB، تعریف کردهایم. سپس نیاز است تا این رشتهی اتصالی را به پروایدر SQL Server مخصوص EF-Core اضافه کنیم. برای اینکار ابتدا باید تغییرات زیر را به فایل MinimalBlog.Api.csproj اعمال کنیم:
که در آن ارجاعاتی به پروژههای Domain و Dal اضافه شدهاست و همچنین بستههای نیوگت EF-Core نیز افزوده شدهاند تا بتوان در فایل Program.cs، تنظیم زیر را اضافه کرد:
در اینجا با استفاده از متد الحاقی AddDbContext، کلاس Context برنامه به مجموعهی سرویسهای آن اضافه شده و همچنین رشتهی اتصالی با کلید Default هم از تنظیمات برنامه، دریافت و به متد UseSqlServer جهت استفاده ارسال شدهاست.
پس از این تنظیمات به پوشهی MinimalBlog.Dal وارد شده و فایل _01-add_migrations.cmd را اجرا میکنیم (این فایل به همراه پیوست قسمت اول، ارائه شدهاست). محتوای این فایل به صورت زیر است:
ابتدا، آخرین نگارش ابزار dotnet-ef را نصب کرده و سپس یکبار هم پروژه را build میکند تا اگر مشکلی باشد، در همینجا با اطلاعات بیشتری نمایش داده شود. سپس با اجرای دستور dotnet ef migrations، کلاسهای Migrations در پوشهای به همین نام تشکیل میشوند.
البته چون کدهای تولید شدهی به صورت خودکار الزاما با Roslyn analyzers برنامه سازگاری ندارند، آنها را توسط فایل مخصوص editorconfig. قرار گرفتهی در پوشهی MinimalBlog.Dal\Migrations، از لیست آنالیزهای برنامه خارج میکنیم. محتوای این فایل ویژه به صورت زیر است:
که سبب خواهد شد تا این پوشهی ویژه به عنوان کدهای به صورت خودکار تولید شده تشخیص داده شود و دیگر آنالیز نشود؛ چون کیفیت آن، مشکل ما نیست!
پس از ایجاد کلاسهای Migration، اکنون نوبت به اجرای آنها بر روی بانک اطلاعاتی است که در رشتهی اتصالی مشخص کردیم. برای اینکار فایل MinimalBlog.Dal\_02-update_db.cmd را اجرا میکنیم که چنین محتویاتی دارد:
در اینجا نیز ابتدا از نصب آخرین نگارش ابزارهای EF اطمینان حاصل میشود. یکبار دیگر نیز پروژه بر اساس فایلهای جدیدی که به آن اضافه شده، کامپایل شده و سپس کلاسهای مهاجرتها، اجرا و اعمال میشوند.
ایجاد مدلها و موجودیتهای برنامهی Minimal Blog
در مثال این سری، هر نویسنده میتواند بلاگ خاص خودش را داشته باشد و در هر بلاگ، تعدادی مقاله منتشر کند. هر مقاله هم میتواند تعدادی تگ یا گروه مرتبط را داشته باشد.
ساختار ابتدایی موجودیت نویسندگان مطالب بلاگ
این موجودیتها در پوشهی جدیدی به نام Model پروژهی MinimalBlog.Domain اضافه خواهند شد:
namespace MinimalBlog.Domain.Model; public class Author { public int Id { get; set; } public string FirstName { get; set; } = default!; public string LastName { get; set; } = default!; public string FullName => FirstName + " " + LastName; public DateTime DateOfBirth { get; set; } public string? Bio { get; set; } }
ساختار ابتدایی موجودیت مقالات بلاگ
namespace MinimalBlog.Domain.Model; public class Article { public Article() { Categories = new List<Category>(); } public int Id { get; set; } public string Title { get; set; } = default!; public string? Subtitle { get; set; } public string Body { get; set; } = default!; public int AuthorId { get; set; } public Author Author { get; set; } = default!; public DateTime DateCreated { get; set; } public DateTime LastUpdated { get; set; } public int NumberOfLikes { get; set; } public int NumberOfShares { get; set; } public ICollection<Category> Categories { get; set; } }
ساختار ابتدایی بلاگهای اختصاصی قابل تعریف
namespace MinimalBlog.Domain.Model; public class Blog { public Blog() { Contributors = new List<Author>(); } public int Id { get; set; } public string Name { get; set; } = default!; public string Description { get; set; } = default!; public DateTime CreatedDate { get; set; } public int AuthorId { get; set; } public Author Owner { get; set; } = default!; public ICollection<Author> Contributors { get; } }
ساختار ابتدایی گروههای مقالات بلاگ
namespace MinimalBlog.Domain.Model; public class Category { public Category() { Articles = new List<Article>(); } public int Id { get; set; } public string Name { get; set; } = default!; public string Description { get; set; } = default!; public ICollection<Article> Articles { get; set; } }
معرفی موجودیتهای تعریف شده به لایهی Dal
لایهی Dal جایی است که DbContext برنامه تعریف میشود و موجودیتها فوق توسط DbSetها در معرض دید EF-Core قرار میگیرند. به همین جهت ابتدا فایل MinimalBlog.Dal.csproj را به صورت زیر تغییر میدهیم:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> <ProjectReference Include="..\MinimalBlog.Domain\MinimalBlog.Domain.csproj" /> </ItemGroup> <ItemGroup> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.2"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> </ItemGroup> </Project>
به علاوه تعاریفی مانند ImplicitUsings و Nullable را هم مشاهده میکنید که با توجه به استفادهی از فایل Directory.Build.props غیرضروری و تکراری هستند؛ چون این فایل مخصوص به همراه این تعاریف سراسری نیز هست.
سپس به پروژهی Dal، کلاس جدید MinimalBlogDbContext را به صورت زیر اضافه میکنیم تا مدلهای برنامه را در معرض دید EF-Core قرار دهد:
using Microsoft.EntityFrameworkCore; using MinimalBlog.Domain.Model; namespace MinimalBlog.Dal; public class MinimalBlogDbContext : DbContext { public MinimalBlogDbContext(DbContextOptions options) : base(options) { } public DbSet<Article> Articles { get; set; } = default!; public DbSet<Category> Categories { get; set; } = default!; public DbSet<Author> Authors { get; set; } = default!; public DbSet<Blog> Blogs { get; set; } = default!; }
ایجاد و اجرای Migrations
پس از تعریف MinimalBlogDbContext، اکنون نوبت به ایجاد کلاسهای Migrations و اجرای آنها جهت ایجاد بانک اطلاعاتی متناظر با مدلهای برنامه است. برای این منظور در ابتدا به پروژهی Api مراجعه کرده و فایل appsettings.json را به صورت زیر تکمیل میکنیم:
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*", "ConnectionStrings": { "Default": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=MinimalBlog;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False" } }
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>net6.0</TargetFramework> <Nullable>enable</Nullable> <ImplicitUsings>enable</ImplicitUsings> </PropertyGroup> <ItemGroup> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.2"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> </ItemGroup> <ItemGroup> <ProjectReference Include="..\MinimalBlog.Domain\MinimalBlog.Domain.csproj" /> <ProjectReference Include="..\MinimalBlog.Dal\MinimalBlog.Dal.csproj" /> </ItemGroup> </Project>
using Microsoft.EntityFrameworkCore; using MinimalBlog.Dal; var builder = WebApplication.CreateBuilder(args); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var connectionString = builder.Configuration.GetConnectionString("Default"); builder.Services.AddDbContext<MinimalBlogDbContext>(opt => opt.UseSqlServer(connectionString));
پس از این تنظیمات به پوشهی MinimalBlog.Dal وارد شده و فایل _01-add_migrations.cmd را اجرا میکنیم (این فایل به همراه پیوست قسمت اول، ارائه شدهاست). محتوای این فایل به صورت زیر است:
For /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set mydate=%%c_%%a_%%b) For /f "tokens=1-2 delims=/:" %%a in ("%TIME: =0%") do (set mytime=%%a%%b) dotnet tool update --global dotnet-ef --version 6.0.2 dotnet build dotnet ef migrations --startup-project ../MinimalBlog.Api/ add V%mydate%_%mytime% --context MinimalBlogDbContext pause
البته چون کدهای تولید شدهی به صورت خودکار الزاما با Roslyn analyzers برنامه سازگاری ندارند، آنها را توسط فایل مخصوص editorconfig. قرار گرفتهی در پوشهی MinimalBlog.Dal\Migrations، از لیست آنالیزهای برنامه خارج میکنیم. محتوای این فایل ویژه به صورت زیر است:
[*.cs] generated_code = true
پس از ایجاد کلاسهای Migration، اکنون نوبت به اجرای آنها بر روی بانک اطلاعاتی است که در رشتهی اتصالی مشخص کردیم. برای اینکار فایل MinimalBlog.Dal\_02-update_db.cmd را اجرا میکنیم که چنین محتویاتی دارد:
dotnet tool update --global dotnet-ef --version 6.0.2 dotnet build dotnet ef --startup-project ../MinimalBlog.Api/ database update --context MinimalBlogDbContext pause
- Hello World براساس سن و شغل! | پویا | zombie-geek.net
- بهبود رتبه سایت - جدول تناوبی سئو | (مجتبی بنائی) | www.banaie.ir
- راهنمای تنظیم فایرفاکس ۷ برای نشان دادن http:// در آدرس صفحات | مدیریت مجله نودایران | nodiran.com
- مدیر پروژه باید منبع آرامش باشد، مثل خولیو بلاسکو | مهدی عرب عامری | pmplus.ir
- Babel Obfuscator 4.3.0.0 منتشر شد | babelobfuscator.blogspot.com
- Lambdas در C++11 | geekswithblogs.net
- Visual Studio 2010 Feature Pack 2 منتشر شد | geekswithblogs.net
- Windows Phone SDK 7.1 منتشر شد | windowsteamblog.com
- Windows Simulator جهت توسعه برنامههای مخصوص ویندوز 8 | blogs.msdn.com
- Windows Simulator و دیباگ برنامههای لمسی | blogs.msdn.com
- به روز رسانی اول RAD Studio XE2 و یک سری مشکلات کپی رایت | www.itwriting.com
- پشتیبانی از ایجاد سایههای متنی در IE10 | blogs.msdn.com
- توابع جدید کار با رشتهها در نسخهی بعدی SQL Server | beyondrelational.com
- خلاصهای از مواردی که در نگارش بعدی سی شارپ شاهد خواهیم بود | weblogs.thinktecture.com
- مروری بر قابلیت آنالیز کدهای سی++ در نگارش بعدی ویژوال استودیو | channel9.msdn.com
- - لیست تازههای سرویس پک 2 آفیس 2007 (فقط برای نصب، درایوی که ویندوز بر روی آن نصب است باید نزدیک به 2 گیگ فضای خالی داشته باشد و گرنه در میانه نصب، متوقف خواهد شد؛ همانند نصب سرویس پک یک اس کیوال سرور 2008)
- - سرویس پکهایی که به زودی ارائه میشوند: Windows Server 2008 Service Pack 2 and Windows Vista Service Pack 2
اشتراکها
دفتر کار باز ایده بسیار بدی است!
Not because there aren’t people who actually enjoy working in an open office, there are. Quite a few, actually. But they’re in the distinct minority. The vast majority of people either dislike the open office or downright hate it. So how is that going to work, exactly?
نظرات مطالب
هزینه استفاده از دات نت فریم ورک چقدر است؟
- هر کسی میتونه برای کار خودش مجوز سورس باز انتخاب کنه، و مهم هم نیست که آن کار استاندارد باشد یا نباشد. مثل هزاران کاری که تابحال دیگران انجام دادن.
- در مورد مجوز فقط خواندنی MS-RSL حق با شما است؛ هر چند مثلا ASP.NET MVC3 مجوز MS-PL دارد. ولی ... مهم نیست. مهم این است که سورس آن در دسترس همه است. همین در دسترس بودن سبب شده مونو الان پیاده سازی خوبی رو از ASP.NET MVC 3 ارائه بده:
http://www.mono-project.com/Release_Notes_Mono_2.10#ASP.NET_MVC3_Support
- در مورد مجوز فقط خواندنی MS-RSL حق با شما است؛ هر چند مثلا ASP.NET MVC3 مجوز MS-PL دارد. ولی ... مهم نیست. مهم این است که سورس آن در دسترس همه است. همین در دسترس بودن سبب شده مونو الان پیاده سازی خوبی رو از ASP.NET MVC 3 ارائه بده:
http://www.mono-project.com/Release_Notes_Mono_2.10#ASP.NET_MVC3_Support
نظرات مطالب
هزینه استفاده از دات نت فریم ورک چقدر است؟
- هر کسی میتونه برای کار خودش مجوز سورس باز انتخاب کنه، و مهم هم نیست که آن کار استاندارد باشد یا نباشد. مثل هزاران کاری که تابحال دیگران انجام دادن.
- در مورد مجوز فقط خواندنی MS-RSL حق با شما است؛ هر چند مثلا ASP.NET MVC3 مجوز MS-PL دارد. ولی ... مهم نیست. مهم این است که سورس آن در دسترس همه است. همین در دسترس بودن سبب شده مونو الان پیاده سازی خوبی رو از ASP.NET MVC 3 ارائه بده:
http://www.mono-project.com/Release_Notes_Mono_2.10#ASP.NET_MVC3_Support
- در مورد مجوز فقط خواندنی MS-RSL حق با شما است؛ هر چند مثلا ASP.NET MVC3 مجوز MS-PL دارد. ولی ... مهم نیست. مهم این است که سورس آن در دسترس همه است. همین در دسترس بودن سبب شده مونو الان پیاده سازی خوبی رو از ASP.NET MVC 3 ارائه بده:
http://www.mono-project.com/Release_Notes_Mono_2.10#ASP.NET_MVC3_Support
نمونه از اجرای یم پروژه بات فریم ورک با استفاده از ngrok
In this particular example (Windows 10 with SSD drive with BitLocker enabled) reading 1 MB file is now 2.5 times faster, while writing is 5.5 times faster.
The memory allocations dropped from 39 kilobytes to 192 bytes! This is a 99.5% improvement!
Method | Runtime | Mean | Ratio | Allocated |
---|---|---|---|---|
ReadAsync | .NET 5.0 | 3.419 ms | 1.00 | 39,504 B |
ReadAsync | .NET 6.0 | 1.445 ms | 0.42 | 192 B |
| | | | |
WriteAsync | .NET 5.0 | 12.181 ms | 1.00 | 39,192 B |
WriteAsync | .NET 6.0 | 2.193 ms | 0.18 | 192 B |