از مطلب «کار با چندین نوع بانک اطلاعاتی متفاوت در Entity Framework Core» و همچنین کدهای آن EFCoreMultipleDb.zip ایده بگیرید.
نظرات مطالب
پیاده سازی SoftDelete در EF Core
نکتهای در مورد Owned Entities از EF-Core 3.1 به بعد
از EF-Core 3.1 به بعد، زمان حذف اطلاعات وابستهی به یک رکورد تغییر کردهاست. برای مثال اگر رکوردی به همراه یک owned entity باشد و سعی کنیم آنرا حذف کنیم و این حذف هم از نوع soft delete باشد، کوئری حاصل به همراه نال کردن مقادیر این owned entity هم خواهد بود (حتی اگر این اطلاعات نالپذیر هم نباشند). برای بازگشت به سیستم قبلی و حذف اطلاعات وابسته پس از حذف رکورد اصلی و نه قبل از آن، باید به صورت زیر عمل کرد:
// To fix https://github.com/dotnet/efcore/issues/19786 context.ChangeTracker.CascadeDeleteTiming = CascadeTiming.OnSaveChanges; context.ChangeTracker.DeleteOrphansTiming = CascadeTiming.OnSaveChanges;
اشتراکها
معماری یک برنامه dotcore
ایجاد نام جداول به صورت جمع (Pluralized) و داینامیک :
برای اینکه نام جداول به صورت خودکار به صورت جمع ایجاد شوند میتوان از این متد استفاده کرد:
نحوه فراخوانی در متد OnModelCreating:
هر موجودیتی که اتریبیوت Table داشته باشد از همان نام برای جدول استفاده میشود در غیر اینصورت نام انتیتی به صورت جمع ایجاد میگردد.
هر کلاسی در لایه موجودیتها از BaseEntity ارث بری کرده باشد به عنوان یک Entity شناخته میشود.
اگه از روش خودکار کردن تعاریف DbSet ها استفاده کرده باشیم چون دیگر در داخل کلاس Context برنامه، Dbset تعریف نمیشود معمولا برای نام گذاری جداول که به صورت جمع باشند از اتریبیوت Table استفاده میکنیم.
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; [Table("Users")] public class User : BaseEntity { public long Id { get; set; } [Required] public string FullName { get; set; } = null!; }
using Microsoft.EntityFrameworkCore; using System.ComponentModel.DataAnnotations.Schema; using System.Reflection; namespace ProjectName.Common.EfHelpers; public static class EfToolkit { /// <summary> /// ایجاد نام موجودیتها /// نام موجودیت اگر اتریبیوت تیبل داشته باشد /// از همان نام استفاده میشود و اگر نداشته باشد /// نامش جمع بسته میشود /// </summary> /// <param name="builder"></param> public static void MakeTableNamesPluralized(this ModelBuilder builder) { var entityTypes = builder.Model.GetEntityTypes(); foreach (var entityType in entityTypes) { // Get the CLR type of the entity var entityClrType = entityType.ClrType; var hasTableAttribute = entityClrType.GetCustomAttribute<TableAttribute>(); // Apply the pluralized table name for the entity if (hasTableAttribute is null) { // Get the pluralized table name var pluralizedTableName = GetPluralizedTableName(entityClrType); builder.Entity(entityClrType).ToTable(pluralizedTableName); } } } /// <summary> /// گرفتن نام تایپ و عوض کردن نام آن از مفرد به جمع /// Singular to plural /// Category => Categories /// Box => Boxes /// Bus => Buses /// Computer => Computers /// </summary> /// <param name="entityClrType"></param> /// <returns></returns> private static string GetPluralizedTableName(Type entityClrType) { // Example implementation (Note: This is a simple pluralization logic and might not cover all cases) var typeName = entityClrType.Name; if (typeName.EndsWith("y")) { // Substring(0, typeName.Length - 1) // Range indexer var typeNameWithoutY = typeName[..^1]; return typeNameWithoutY + "ies"; } if (typeName.EndsWith("s") || typeName.EndsWith("x")) { return typeName + "es"; } return typeName + "s"; } }
protected override void OnModelCreating(ModelBuilder builder) { // it should be placed here, otherwise it will rewrite the following settings! base.OnModelCreating(builder); builder.RegisterAllEntities(typeof(BaseEntity)); builder.MakeTableNamesPluralized(); builder.ApplyConfigurationsFromAssembly(typeof(ApplicationDbContext).Assembly); }
قبل از اینکه نام جداول نیز جمع بسته شود تمامی موجودیتها به صورت خودکار اضافه میشوند.
public static class EfToolkit { /// <summary> /// ثبت تمامی انتیتیها /// <param name="builder"></param> /// <param name="type"></param> /// </summary> public static void RegisterAllEntities(this ModelBuilder builder, Type type) { var entities = type.Assembly.GetTypes() .Where(x => x.BaseType == type); foreach (var entity in entities) builder.Entity(entity); } }
اشتراکها
EFCore 5.0 RC1 منتشر شد
Today, the Entity Framework Core team announces the first release candidate (RC1) of EF Core 5.0. This is a feature complete release candidate of EF Core 5.0 and ships with a "go live" license. You are supported using it in production.
پیشنهادها
پردازشهای Async در EF 6
نیاز است خلاصهای از مقالات ذیل به صورت یک مقاله جدید در مورد پردازشهای Async در EF 6 تهیه شود:
- Async in Entity Framework 6.0
- Task-based Asynchronous Pattern support in EF
- Async Query & Save with Entity Framework 6
- Async Query & Save
- Entity Framework asynch – behind the magic
- Performing Asynchronous Operations Using Entity Framework
- EF 6: Async
- Async Processing in EF6 and the Microsoft .NET Framework 4.5
- Build Async Services with ASP.NET Web API and Entity Framework 6
- Making TransactionScope Work with async/await in .NET 4.5
- Async Actions in ASP.NET MVC 4