Jon P. Smith, author of Entity Framework Core in Action, explains what a multi-tenant app is and then digs into the things you need to do to make a multi-tenant app using ASP.NET Core with EF Core.
00:00 Countdown
02:19 Introduction and Community Links
18:25 What are multi-tenant web applications?
21:14 Single level multi-tenant demo
29:00 Partitioning tenants with EF Core QueryFilter
38:00 Admin features: creating users and tenants
43:00 Q&A
43:00 Hierarchical multi-tenant
59:00 How to get started
1:06:30 Database sharding and connection string management
1:16:30 Scaling with Azure SQL Elastic Pools
1:19:00 Conclusion
خطای sql?
- در مطلب قبلی که ارسال کردید چون لاگین نکرده بودید، امکان ویرایش نداشتید. ولی خوب، میتونستید در ادامه آن، بحث را دنبال کنید.
- نگارش 1.8 مدتی هست که منتشر شده. بهتر است از آن استفاده کنید.
- ذکر قسمت parametersValues کاملا اختیاری است. اگر پارامتری ندارید یا اگر شرطی در عبارت SQL خودتون ندارید، آنرا ذکر نکنید:
.MainTableDataSource(dataSource => { dataSource.GenericDataReader( providerName: "System.Data.SQLite", connectionString: "Data Source=" + System.AppDomain.CurrentDomain.BaseDirectory + "\\data\\database.sqlite", sql: @"SELECT id,name,family,mark FROM Student WHERE id='1'" ); })
.MainTableDataSource(dataSource => { dataSource.GenericDataReader( providerName: "System.Data.SQLite", connectionString: "Data Source=" + System.AppDomain.CurrentDomain.BaseDirectory + "\\data\\database.sqlite", sql: @"SELECT id,name,family,mark FROM Student WHERE id= @p1", parametersValues: new object[] { 1 /*مقدار پارامتر اول*/ } ); })
This webcast is a code-focused introduction to developing workflow-enabled Microsoft Windows platform applications. We cover the basics of developing, designing, and debugging workflow solutions. Gain the knowledge and insight you need to be confident choosing workflow for everyday applications.
Intro to Windows Workflow Foundation (Part 2 of 7): Simple Human Workflow Using E-mail (Level 200)
Have you thought about how you might apply the workflow concept to e-mail? In this webcast New Zealand based regional director, Chris Auld, leads attendees through a simple worked example of the use of SMTP e-mail as part of a workflow solution. Chris demonstrates how to create custom activities to query Active Directory to retrieve user data, send e-mail, and wait for e-mail responses to continue the workflow process. This code-intensive session gives users taking their first steps with workflow a good grounding in some of the key extensibility concepts.
Intro to Windows Workflow Foundation (Part 3 of 7): Hosting and Communications Options in Workflow Scenarios (Level 300)
The session looks at options for hosting workflow applications. We cover managing events, instance tracking, and persistence, and provide a close look at the simple communications mechanisms that are available for you to use in your workflow applications.
Intro to Windows Workflow Foundation (Part 4 of 7): Workflow, Messaging, and Services: Developing Distributed Applications with Workflows (Level 300)
Web service technologies have typically taken a "do-it-yourself" approach to maintaining the interoperation state of services. Using workflow, developers now have tools that allow them to describe the long-running state of their services and delegate much of the state management to the underlying platform. Managing this state correctly becomes even more challenging in applications that coordinate work across multiple services either within an organization or at an Internet scale. This session looks at how developers who use either Microsoft ASMX or Microsoft's framework for building service-oriented applications, code-named "Indigo", can create workflow-oriented applications that are both faster to write and more manageable and flexible once deployed.
Intro to Windows Workflow Foundation (Part 5 of 7): Developing Event Driven State Machine Workflows (Level 300)
State machines used to be something that you had to first draw on paper and then implement in code. This session shows how to use technologies to create event-driven workflows and how to apply this to a typical programming problem. We introduce the concept of a flexible process and show how this can help with modeling real-world processes using state and sequential workflow. Plenty of coding is included to illustrate how you can seamlessly merge state machine design and your code.
Intro to Windows Workflow Foundation (Part 6 of 7): Extending Workflow Capabilities with Custom Activities (Level 300)
It is helpful to think of activities as controls within a workflow, similar to controls used with Microsoft ASP.NET Pages or Microsoft Windows Forms. You can use activities to encapsulate execution logic, communicate with the host and decompose a workflow into reusable components. This session examines the simple process of creating custom activities. If you want to expose activities to other developers designing workflows, you are likely to find this session valuable.
Intro to Windows Workflow Foundation (Part 7 of 7): Developing Rules Driven Workflows (Level 300)
Rules can be a powerful business tool when combined with workflow. In this session, learn how to develop more advanced activities that support the modeling of rich business behavior such as human workflow. Understand when to use rules for business logic, and see how rule policies allow for the description of sophisticated behavior in an integrated and flexible way. This session gives you an interesting insight into the power of using workflow at the core of a line of business application.
public class XamAppExceptionHandler : BitExceptionHandler { public override void OnExceptionReceived(Exception exp, IDictionary<string, string> properties = null) { #if DEBUG System.Diagnostics.Debugger.Break(); #endif base.OnExceptionReceived(exp, properties); } }
BitExceptionHandler.Current = new XamAppExceptionHandler();
حال برای لاگ کردن این خطاها، میتوانید از Microsoft's AppCenter استفاده کنید. استفاده از امکانات App Center رایگان بوده و برای استفادهی در ایران محدودیتی ندارد. ابتدا در سایت مربوطه ثبت نام کنید و سپس سه بار Add New app را بزنید و به نامهای XamApp_Windows، XamApp_iOS و XamApp_Android سه برنامه را بسازید و برای Android و iOS گزینهی Xamarin را انتخاب و برای ویندوز نیز UWP را انتخاب کنید.
سپس پکیجهای Microsoft.AppCenter.Crashes و Microsoft.AppCenter.Analytics را بر روی XamApp نصب نموده و کد زیر را در سه فایل AppDelegate.cs/MainActivity.cs/App.xaml.cs برای iOS/Android/Windows کپی کنید:
AppCenter.Start("copy-your-guid-key-for-iOS-Android-Windows-here", typeof(Crashes), typeof(Analytics));
برای هر یک از برنامههای Android/iOS/Windows یک Guid متفاوت دارید که در قسمت Getting Started در سایت App Center میتوانید آنها را مشاهده کنید. هر بار که این کد را کپی میکنید، مقدار Guid درست را بگذارید.
برای گزارش کردن خطاهای برنامه، کافی است کد زیر را به XamAppExceptionHandler.cs که در ابتدای این قسمت در موردش صحبت کرده بودیم اضافه کنید:
Crashes.TrackError(exp, properties);
حال اگر برنامه را اجرا و شروع به تست کنید و یا آن را در اختیار تسترها و مشتریها بگذارید، نه تنها گزارش تمامی خطاها و کرشها را خواهید داشت که حتی آمار استفاده کنندههای برنامه (شامل کشور و مشخصات دستگاه و ...) را نیز خواهید داشت.
حال در یک کد ده خطی، اگر در خط پنجم خطایی رخ دهد، اگر چه باعث بسته شدن برنامه نمیشود و لاگ نیز میشود، ولی در مواقعی خیلی خاص، شاید بخواهید در صورت رخ دادن خطا، چند خط کد بعدی کماکان اجرا شوند. در این حالت شما Try/Catch مینویسید که برای عبور کردن از خطا از آن استفاده کردهاید. در این صورت، ترجیحا آن را به شکل زیر بنویسید:
// code 1... try { // code 2... } catch (Exception ex) { BitExceptionHandler.Current.OnExceptionReceived(ex, new Dictionary<string, string> { { "SomeData", "2" } }); } // code 3...
در این کد مثال، فرض کنیم که برخی اوقات در code 2 خطایی رخ میدهد که برای ما مهم نیست و میخواهیم حتی در صورت رخ دادن خطا، code 3 اجرا شود. توصیه میکنیم در این موارد که در برنامه خیلی هم نباید متداول باشد، لااقل خطا را با کمک کد BitExceptionHandler.Current.OnExceptionReceived لاگ کنید و همچنین با داشتن یک Dictionary میتوانید حتی دیتای بیشتری را نیز به AppCenter فرستاده و در پرتال مربوطه مشاهده کنید.
به صورت کلی بهتر است از این نوع Try/Catchها پرهیز کنید و حتی اگر جایی Catch ای نوشتید، در نهایت دوباره خطا را throw کنید.
try { // some codes... } catch { // Do something related to exception... // for example, show some alerts to the user. throw; // You don't need to call BitExceptionHandler.Current.OnExceptionReceived... }
در مثال فوق، قصد داریم وقتی خطایی رخ داد، پیامی را به کاربر اطلاع دهیم. در این صورت، پس از نمایش پیام مربوطه، مجددا خطا را throw کنید. در این صورت، نیازی به فراخوانی BitExceptionHandler.Current.OnExceptionReceieved نیز نیست.
البته AppCenter در زمینه پابلیش کردن برنامه و همچنین Push Notification و ... نیز دارای امکاناتی هست که به موضوع این قسمت ارتباطی ندارند.
MySQL مدتی است که جزو یکی از محصولات شرکت اوراکل محسوب شده و توسعه دهندگان تجاری باید برای استفاده از آن هزینه کنند. این هزینه نیز اخیرا افزایش یافته و به حداقل 2000 دلار به ازای هر سرور رسیده است (+). این عدد واقعا رقم بالایی برای محصولی محسوب میشود که بسیاری از توسعه دهندهها تصور میکنند رایگان است. استفاده از این محصول با توجه به مدل تجاری جدید آن فقط در پروژههای سورس باز رایگان است (بله فقط در پروژههایی که با مجوز GPL منتشر شوند) و اگر شما یک سیستم تجاری کلاینت سرور را بر این اساس طراحی کنید حتما باید هزینههای مرتبط را نیز پرداخت نمائید (+).
توضیحی در مورد GPL و MySQL
The change from the LGPL to the GPL for the client libraries was made in 2001 during the development of MySQL 4.0 to help MySQL AB more easily differentiate between a proprietary user who should buy a commercial license and a free software user who should use the GPL license.
MySQL با توجه به مجوز GPL آن در شرایط زیر رایگان خواهد بود:
- قصد توزیع مجدد آنرا نداشته باشید.
- همچنین برنامهی شما نیز به صورت سورس باز تحت مجوز GPL ارائه گردد.
و تنها زمانی در مورد MySQL باید هزینه کنید که:
-قصد توزیع مجدد آنرا داشته باشید.
-برنامهی شما سورس باز نبوده و قصد ندارید آنرا تحت مجوز GPL ارائه دهید. (که عموما در مورد برنامههای تجاری به همین صورت است)
نکتهی دیگری را که باید به آن دقت داشت این است که برای واگذاری MySQL به شرکت اوراکل، اتحادیه اروپا نیز با توجه به وجود بیش از 50 هزار توسعه دهندهی اروپایی که از MySQL استفاده میکنند، شرکت اوراکل را موظف کرده است تا این dual licensing (تجاری و سورس باز) را تا سال 2015 حفظ کرده و ادامه دهد (+). به این معنا که شرکت اوراکل پس از سال 2015 هیچگونه تعهدی به ارائهی نگارش سورس باز این محصول به هیچ نهاد و یا سازمانی ندارد.
البته اینها به معنای پایان دنیا نیست. هم اکنون چهار fork سورس باز از این محصول وجود دارند (Drizzle ، MariaDB ، OurDelta و Percona Server) ولی تنها آینده است که میزان موفقیت، پایداری و تداوم آنها را مشخص خواهد کرد.
این فرم دارای اطلاعاتی شامل : نام، جنسیت ، زمینههای کاری، کشور، تاریخ تولد و تصویر میباشد.
TextBlock
همان Label قدیمی خودمان است که برای نمایش متون کاربر دارد. متن داخل آن بین دو تگ قرار میگیرد و یا از خاصیت Text آن کمک گرفته خواهد شد. حتما از خاصیت Width و height آن برای مقداردهی کمک بگیرید، زیرا در غیر آن صورت کل Container خود را خواهد پوشاند. در صورتی که متنی در مکان خود جا نشود میتوان از دو ویژگی استفاده کرد. آن را برش داد یا به خطوط بعدی شکست. برای حذف یا برش باقی مانده متن میتوان از خصوصیت TextTrimming استفاده کرد که سه مقدار میگیرد:
None مقدار پیش فرض
CharacterEllipsis با نزدیک شدن به آخر پهنای کار از ... استفاده مینماید. در صورتی که لیستی یا مورد مشابهی دارید میتواند بسیار کاربردی باشد.
WordEllipsis این گزینه هم مانند مورد بالاست با این تفاوت که سعی دارد تا آنجا که ممکن است خود را به آخرین حرف کلمه برساند تا شکستگی در وسط کلمه اتفاق نیفتد و آخرین کلمه کامل دیده شود و بعد ... قرار بگیرد؛ هر چند در تستهای خودم تفاوتی مشاهده نکردم.
گزینه TextWrapping جهت شکستن یک خط به خطوط است؛ موقعی که متن شما به انتهای صفحه میرسد، این ویژگی باعث میشود متن به بیرون از پنجره نرفته و یک خط به سمت پایین حرکت کند. این گزینه سه مقدار را دارد:
تصویر زیر حالت اصلی نمایش بدون نیاز به Wrap شدن است:
None: مقدار پیش فرض که خصوصیت Wrap را به همراه ندارد.
Wrap: فعال سازی ویژگی TextWrapping
WrapWithOverflow: فرق این گزینه با گزینه بالا در این است که ، گزینه بالا در هر موقعیتی که پیش بیاید عمل خط شکن را روی عبارت یا حتی آن کلمه انجام میدهد. ولی در این گزینه فرصت خط شکنی مثل بالا فراهم نیست و اگر روی کلمهای خط شکنی رخ دهد، مابقی آن کلمه از ناحیهی خودش خارج شده و از کلمهی بعدی، خط شکنی صورت میگیرد.
خصوصیت LineStackingStrategy:
این خصوصیت فاصلهی بین خطوط را با استفاده از یک واحد منطقی dp مشخص میکند. هر چند دو گزینه دیگر هم دارد که دو تصویر زیر را در این صفحه به شما نمایش میدهد:
برای ساخت فرم از یک گرید با سه ستون و 6 سطر استفاده میکنم.
<Grid Margin="5"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"></ColumnDefinition> <ColumnDefinition Width="*"></ColumnDefinition> <ColumnDefinition Width="Auto"></ColumnDefinition> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition Height="Auto"></RowDefinition> </Grid.RowDefinitions> </Grid>
در داخل گرید بعد از تعریف سطر و ستون، همانطور که قبلا توضیح دادیم کنترلهای TextBlock را اضافه میکنیم:
<TextBlock Grid.Column="0" Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Left" >Name</TextBlock> <TextBlock Grid.Column="0" Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Left" >Gender</TextBlock> <TextBlock Grid.Column="0" Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Left" >Field Of Work</TextBlock> <TextBlock Grid.Column="0" Grid.Row="3" VerticalAlignment="Center" HorizontalAlignment="Left" >Country</TextBlock> <TextBlock Grid.Column="0" Grid.Row="4" VerticalAlignment="Center" HorizontalAlignment="Left" >Birth Date</TextBlock> <TextBox Grid.Row="0" Grid.Column="1" Name="Txtname" HorizontalAlignment="Left" Margin="5" Width="200" ></TextBox>
Buttons
برای فیلد جنسیت Gender هم از RadioButton کمک گرفتم که با استفاده از خاصیت GroupName میتوان دستهای از این کنترلها را با هم مرتبط ساخت تا با انتخاب یک آیتم جدید از همان گروه، آیتم قبلی که انتخاب شده بود از حالت انتخاب خارج شده و آیتم جدیدی انتخاب شود. از خاصیت IsChecked میتوان برای انتخاب یک آیتم بهره برد.
به صورت کلی دکمهها به چند دسته زیر تقسیم میشوند:
- Button
- ToggleButton
- CheckBox
- RadioButton
که همگی این عناصر از کلاسی به نام ButtonBase مشتق شده اند. کد زیر RadioButtonها را به صورت عمودی چینش کرده است:
<StackPanel Orientation="Vertical" Grid.Row="1" Grid.Column="1" Margin="10"> <RadioButton GroupName="Gender" Name="RdoMale" IsChecked="True" >Male</RadioButton> <RadioButton GroupName="Gender" Name="RdoFemale" Margin="0 5 0 0" >Female</RadioButton> </StackPanel>
<StackPanel Orientation="Horizontal" Grid.Row="2" Grid.Column="1" Margin="10"> <CheckBox Name="ChkActor" >Actor/Actress</CheckBox> <CheckBox Name="ChkDirector" >Director</CheckBox> <CheckBox Name="ChkProducer" >Producer</CheckBox> </StackPanel> <ListBox Grid.Row="3" Grid.Column="1" Margin="10" Height="80"> <ListBoxItem> <TextBlock>UnitedStates</TextBlock> </ListBoxItem> <ListBoxItem> <TextBlock >UK</TextBlock> </ListBoxItem> <ListBoxItem> <TextBlock >France</TextBlock> </ListBoxItem> <ListBoxItem> <TextBlock >Japan</TextBlock> </ListBoxItem> </ListBox> <Calendar Grid.Row="4" Grid.Column="1" HorizontalAlignment="Left" Margin="10"></Calendar>
<Grid Grid.Row="0" Grid.Column="2" Grid.RowSpan="4"> <Grid.RowDefinitions> <RowDefinition Height="*"></RowDefinition> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"></ColumnDefinition> </Grid.ColumnDefinitions> <Image HorizontalAlignment="Right" Source="man.jpg" Stretch="UniformToFill" VerticalAlignment="Top" Width="100" Height="150"></Image> <Button Width="25" Height="15" Padding="0" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="0,0,0,83"> <TextBlock VerticalAlignment="Center" Margin="0 -7 0 0">...</TextBlock> </Button> </Grid>
None: تصویر، اندازهی اصلی خود را حفظ کرده و هر مقدار آن که در کنترل جا شود، نمایش مییابد و بسته به سایز تصویر ممکن است گوشه هایی از تصویر نمایش نیابد.
Fill: تصویر را داخل کنترل به زور جا داده تا پهنا و ارتفاع عکس، هم اندازه کنترل میشود.
Uniform: تصویر بزرگ را با در نظر گرفتن نسبت پهنا و ارتفاع تصویر، با یکدیگر در کنترل جا میدهد.
UniformToFill: تصویر، کل کنترل را میگیرد ولی نسبت پهنا و عرض را حفظ کرده ولی قسمت هایی از تصویر در کنترل دیده نمیشود.
همانطور که قبلا هم گفتیم، خود کنترل دکمه شامل زیر کنترلهایی میشود که یکی از آنها TextBlock است و از طریق خصوصیت *.TextBlock دیگر خصوصیات آن قابل تنظیم است و البته برای خصوصی سازی بیشتر هم میتوان یک TextBlock را به صورت Nested یعنی داخل تگ Button تعریف کنید که ما همین کار را کرده ایم.
فرم نهایی ما به صورت زیر است:
در صورتی که دوست دارید جهت ListBox را از عمودی به افقی تغییر دهید میتوانید از پنلهای Stack یا Wrap استفاده کنید که تعریف آن به شکل زیر است:
<ListBox> <ListBox.ItemsPanel> <ItemsPanelTemplate> <VirtualizingStackPanel Orientation="Horizontal" /> </ItemsPanelTemplate> </ListBox.ItemsPanel> </ListBox>
بدین صورت ListBox به شکل زیر تغییر مییابد:
و در صورتی که میخواهید Scroll حذف شود و از Wrap استفاده کنید، کد را به شکل زیر تعریف کنید. فراموش نکنید که اسکرول افقی را غیرفعال کنید؛ وگرنه نتیجه کار به شکل بالا خواهد بود.
<ListBox ScrollViewer.HorizontalScrollBarVisibility="Disabled"> <ListBox.ItemsPanel> <ItemsPanelTemplate> <WrapPanel /> </ItemsPanelTemplate> </ListBox.ItemsPanel> </ListBox>
Calendar
تقویم یکی دیگر از کنترلهای موجود است که شامل خصوصیات زیر است:
DisplayDate: تاریخ پیش فرض و اولیه تقویم را مشخص میکند؛ در صورتی که ذکر نشود تاریخ جاری درج میشود.
<Calendar DisplayDate="01.01.2010" />
<Calendar DisplayDateStart="01.01.2015" DisplayDateEnd="05.01.2015" />
SelectionMode: نحوهی انتخاب تاریخ را مشخص میکند:
SingleDate: فقط یک تاریخ قابل انتخاب است.
SingleRange: میتوانید از یک تاریخ تا تاریخ دیگر را انتخاب کنید. ولی نمیتوانید مجددا چند انتخاب دیگر را در جای جای تقویم داشته باشید. مثلا از تاریخ 5 آپریل تا 10 آپریل را انتخاب کردهاید؛ ولی دیگر نمیتوانید تاریخ 15 آپریل یا محدودهی 15 آپریل تا 20 آپریل را انتخاب کنید. چون تنها قادر به انتخاب یک رنج یا محدوده تاریخی هستید.
MultipleRanges: بر خلاف گزینهی بالایی هر محدوده تاریخی قابل انتخاب است.
<Calendar SelectionMode="MultipleRange" />
نکته بعدی در مورد غیرفعال کردن بعضی از تاریخ هاست که شما قصد ندارید به کاربر اجازه دهید آنها را انتخاب کند. برای مثال تاریخهای 1 آپریل تا 10 آپریل را از دسترس خارج کنید. برای همین از خصوصیت BlackoutDates استفاده میکنیم که نحوهی تعریف آن به شرح زیر است که در این کد دو محدودهی تاریخی غیر فعال شده اند:
<Calendar> <Calendar.BlackoutDates> <CalendarDateRange Start="01/01/2010" End="01/06/2010" /> <CalendarDateRange Start="05/01/2010" End="05/03/2010" /> </Calendar.BlackoutDates> </Calendar>
DisplayMode : به طور پیش فرض، تقویم ماهها را نشان میدهد ولی میتوانید آن را توسط این خصوصیت روی سال یا دهه و ماه هم تنظیم کنید.
با انتخاب سال Year، تقویم ماههای یک سال را نمایش میدهد.
با انتخاب دهه Decades سالهای یک دههی تعیین شده را نشان میدهد و با انتخاب ماه Month روزهای هر ماه در آن نمایش داده میشود.
در هنگام انتخاب این گزینه، به داخل تقویم نگاه نکنید، بلکه به سر تیتر آن نگاه کنید.
<Calendar DisplayMode="Year" />
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net7.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.10"> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <PrivateAssets>all</PrivateAssets> </PackageReference> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.10" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.10"> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <PrivateAssets>all</PrivateAssets> </PackageReference> </ItemGroup> </Project>
dotnet tool update --global dotnet-ef --version 7.0.10
dotnet ef dbcontext scaffold "Data Source=(localdb)\mssqllocaldb;Initial Catalog=DbName;Encrypt=false;" Microsoft.EntityFrameworkCore.SqlServer -o Output -f
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net7.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.10"> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <PrivateAssets>all</PrivateAssets> </PackageReference> <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="7.0.0" /> <PackageReference Include="Pomelo.EntityFrameworkCore.MySql.Design" Version="1.1.2" /> </ItemGroup> </Project>
dotnet tool update --global dotnet-ef --version 7.0.10
dotnet ef dbcontext scaffold "server=localhost;port=3306;user=root;password=MyPass;database=MyDbName;TreatTinyAsBoolean=true;AllowZeroDateTime=true;ConvertZeroDateTime=true;" Pomelo.EntityFrameworkCore.MySql -o Output -f
ج) Postgres
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net7.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.10"> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <PrivateAssets>all</PrivateAssets> </PackageReference> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.10"> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <PrivateAssets>all</PrivateAssets> </PackageReference> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="7.0.4"/> </ItemGroup> </Project>
dotnet tool update --global dotnet-ef --version 7.0.10
dotnet ef dbcontext scaffold "User ID=Vahid;Password=MyPass;Host=localhost;Port=5432;Database=MyDbName;Pooling=true;" Npgsql.EntityFrameworkCore.PostgreSQL -o Output -f
د) SQLite
وابستگیهای مورد نیاز در یک پروژهی classlib فرضی:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net7.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.10"> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <PrivateAssets>all</PrivateAssets> </PackageReference> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.10" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="7.0.10" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.10"> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <PrivateAssets>all</PrivateAssets> </PackageReference> </ItemGroup> </Project>
dotnet tool update --global dotnet-ef --version 7.0.10
dotnet ef dbcontext scaffold "Data Source=C:\\Path\\db.sqlite" Microsoft.EntityFrameworkCore.Sqlite -o Output