Aracılığıyla paylaş


Özel Tersine Mühendislik Şablonları

Dekont

Bu özellik EF Core 7'ye eklendi.

Tersine mühendislikle çalışırken Entity Framework Core, çeşitli uygulama türlerinde kullanılabilen ve tutarlı bir görünüm ve tanıdık bir görünüm için yaygın kodlama kurallarını kullanan iyi, genel amaçlı kodun iskelesini oluşturmaya çalışır. Ancak bazen daha özel kod ve alternatif kodlama stilleri tercih edilir. Bu makalede, T4 metin şablonlarını kullanarak yapı iskelesi oluşturulmuş kodun nasıl özelleştirileceği gösterilmektedir.

Ön koşullar

Bu makalede EF Core'da tersine mühendislik hakkında bilgi sahibi olduğunuz varsayılır. Aksi takdirde devam etmeden önce lütfen bu makaleyi gözden geçirin.

Varsayılan şablonları ekleme

yapı iskelesi kodunu özelleştirmenin ilk adımı, projenize varsayılan şablonları eklemektir. Varsayılan şablonlar, tersine mühendislik sırasında EF Core tarafından dahili olarak kullanılan şablonlardır. bunlar, iskelelenmiş kodu özelleştirmeye başlamanız için bir başlangıç noktası sağlar.

için EF Core şablon paketini dotnet newyükleyerek başlayın:

dotnet new install Microsoft.EntityFrameworkCore.Templates

Artık projenize varsayılan şablonları ekleyebilirsiniz. Bunu yapmak için proje dizininizden aşağıdaki komutu çalıştırın.

dotnet new ef-templates

Bu komut projenize aşağıdaki dosyaları ekler.

  • CodeTemplates/
    • EFCore/
      • DbContext.t4
      • EntityType.t4

Şablon DbContext.t4 , veritabanı için bir DbContext sınıfının iskelesini oluşturmak için kullanılır ve EntityType.t4 şablon, veritabanındaki her tablo ve görünüm için varlık türü sınıflarını iskeleye almak için kullanılır.

Bahşiş

Visual Studio'nun şablonları dönüştürmesini önlemek için .t4 uzantısı (.tt yerine) kullanılır. Şablonlar bunun yerine EF Core tarafından dönüştürülür.

T4'e Giriş

Şimdi şablonu açalım DbContext.t4 ve içeriğini inceleyelim. Bu dosya bir T4 metin şablonudur. T4, .NET kullanarak metin oluşturmaya yönelik bir dildir. Aşağıdaki kod yalnızca açıklayıcı amaçlara yöneliktir; dosyanın tüm içeriğini temsil etmez.

Önemli

T4 metin şablonlarını (özellikle kod oluşturanlar) söz dizimi vurgulamadan okumak zor olabilir. Gerekirse, kod düzenleyicinizin T4 söz dizimi vurgulamasını etkinleştiren bir uzantısını arayın.

<#@ template hostSpecific="true" #>
<#@ assembly name="Microsoft.EntityFrameworkCore.Design" #>
<#@ parameter name="NamespaceHint" type="System.String" #>
<#@ import namespace="Microsoft.EntityFrameworkCore" #>
<#
    if (!string.IsNullOrEmpty(NamespaceHint))
    {
#>
namespace <#= NamespaceHint #>;

ile <#@ başlayan ilk birkaç satır yönerge olarak adlandırılır. Bunlar, şablonun nasıl dönüştürüldüğünü etkiler. Aşağıdaki tabloda, kullanılan her yönerge türü kısaca açıklanmaktadır.

Yönerge Tanım
template EF Core hizmetlerine erişmek için şablonun Host içindeki özelliğin kullanılmasını sağlayan hostSpecific="true" öğesini belirtir.
assembly Şablonu derlemek için gereken derleme başvurularını ekler.
parameter Şablonu dönüştürürken EF Core tarafından geçirilecek parametreleri bildirir.
import C# kullanma yönergeleri gibi, şablon kodu için ad alanlarını kapsama getirir.

yönergelerinden sonra öğesinin sonraki bölümüne DbContext.t4 denetim bloğu adı verilir. Standart denetim bloğu ile <# başlar ve ile #>biter. şablonu dönüştürürken içindeki kod yürütülür. Denetim bloklarında kullanılabilen özelliklerin ve yöntemlerin listesi için bkz. TextTransformation sınıfı.

Denetim bloğu dışındaki her şey doğrudan şablon çıkışına kopyalanır.

İfade denetim bloğu ile <#=başlar. İçindeki kod değerlendirilir ve sonuç şablon çıkışına eklenir. Bunlar C# ilişkilendirmeli dize bağımsız değişkenlerine benzer.

T4 söz diziminin daha ayrıntılı ve eksiksiz bir açıklaması için bkz . T4 Metin Şablonu Yazma.

Varlık türlerini özelleştirme

Şimdi şablonu özelleştirmenin nasıl bir şey olduğunu inceleyelim. Varsayılan olarak, EF Core koleksiyon gezinti özellikleri için aşağıdaki kodu oluşturur.

public virtual ICollection<Album> Albums { get; } = new List<Album>();

Çoğu List<T> uygulama için kullanmak iyi bir varsayılan değerdir. Ancak WPF, WinUI veya .NET MAUI gibi XAML tabanlı bir çerçeve kullanıyorsanız, genellikle bunun yerine veri bağlamayı etkinleştirmek istersiniz ObservableCollection<T> .

EntityType.t4 Şablonu açın ve oluşturduğu List<T>yeri bulun. Şunun gibi görünür:

    if (navigation.IsCollection)
    {
#>
    public virtual ICollection<<#= targetType #>> <#= navigation.Name #> { get; } = new List<<#= targetType #>>();
<#
    }

List değerini ObservableCollection ile değiştirin.

public virtual ICollection<<#= targetType #>> <#= navigation.Name #> { get; } = new ObservableCollection<<#= targetType #>>();

Ayrıca, iskelesi oluşturulmuş koda bir using yönerge eklememiz gerekir. Usings, şablonun üst kısmındaki bir listede belirtilir. Listeye ekleyin System.Collections.ObjectModel .

var usings = new List<string>
{
    "System",
    "System.Collections.Generic",
    "System.Collections.ObjectModel"
};

Tersine mühendislik komutlarını kullanarak değişiklikleri test edin. Projenizdeki şablonlar komutlar tarafından otomatik olarak kullanılır.

dotnet ef dbcontext scaffold "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=Chinook" Microsoft.EntityFrameworkCore.SqlServer

Komutu daha önce çalıştırdıysanız mevcut dosyaların üzerine yazma seçeneğini ekleyin --force .

Her şeyi doğru yaptıysanız, koleksiyon gezinti özellikleri artık kullanmalıdır ObservableCollection<T>.

public virtual ICollection<Album> Albums { get; } = new ObservableCollection<Album>();

Şablonları güncelleştirme

Projenize varsayılan şablonları eklediğinizde, EF Core'un bu sürümünü temel alan bir kopyasını oluşturur. Hatalar düzeltildikçe ve EF Core'un sonraki sürümlerinde özellikler eklendikçe şablonlarınız güncel olmayabilir. EF Core şablonlarında yapılan değişiklikleri gözden geçirmeli ve bunları özelleştirilmiş şablonlarınızla birleştirmelisiniz.

EF Core şablonlarında yapılan değişiklikleri gözden geçirmenin bir yolu, git kullanarak bunları sürümler arasında karşılaştırmaktır. Aşağıdaki komut EF Core deposunu kopyalayacak ve bu dosyaların 7.0.0 ve 8.0.0 sürümleri arasında farkını oluşturacaktır.

git clone --no-checkout https://github.com/dotnet/efcore.git
cd efcore
git diff v7.0.0 v8.0.0 -- src/EFCore.Design/Scaffolding/Internal/CSharpDbContextGenerator.tt src/EFCore.Design/Scaffolding/Internal/CSharpEntityTypeGenerator.tt

Değişiklikleri gözden geçirmenin bir diğer yolu da NuGet'ten Microsoft.EntityFrameworkCore.Templates'ın iki sürümünü indirmek, içeriklerini ayıklamak (dosya uzantılarını .zip olarak değiştirebilirsiniz) ve bu dosyaları karşılaştırmaktır.

Varsayılan şablonları yeni bir projeye eklemeden önce en son EF Core şablon paketine güncelleştirmeyi unutmayın.

dotnet new update

Gelişmiş kullanım

Giriş modelini yoksayma

Model ve EntityType parametreleri veritabanına eşlemenin olası bir yolunu temsil eder. Modelin bölümlerini yoksaymayı veya değiştirmeyi seçebilirsiniz. Örneğin, sağladığımız gezinti adları ideal olmayabilir ve kodun iskelesini oluştururken bunları kendinizle değiştirebilirsiniz. Kısıtlama adları ve dizin filtreleri gibi diğer öğeler yalnızca Geçişler tarafından kullanılır ve geçişleri iskelelenmiş kodla kullanmayı düşünmüyorsanız modelden güvenle atlanabilir. Benzer şekilde, uygulamanız tarafından kullanılmadıysa dizileri veya varsayılan kısıtlamaları atlamak isteyebilirsiniz.

Bunun gibi gelişmiş değişiklikler yaparken, sonuçta elde edilen modelin veritabanıyla uyumlu kaldığından emin olun. tarafından dbContext.Database.GenerateCreateScript() oluşturulan SQL'i gözden geçirmek, bunu doğrulamanın iyi bir yoludur.

Varlık yapılandırma sınıfları

Büyük modeller için, DbContext sınıfının OnModelCreating yöntemi yönetilemeyecek kadar büyük olabilir. Bu sorunu gidermenin bir yolu sınıfları kullanmaktır IEntityTypeConfiguration<T> . Bu sınıflar hakkında daha fazla bilgi için bkz . Model oluşturma ve yapılandırma.

Bu sınıfların iskelesini oluşturmak için adlı EntityTypeConfiguration.t4üçüncü bir şablon kullanabilirsiniz. Şablon gibi modeldeki EntityType.t4 her varlık türü için kullanılır ve şablon parametresini EntityType kullanır.

Diğer dosya türlerinin iskelesini oluşturma

EF Core'da tersine mühendisliğin birincil amacı, DbContext ve varlık türlerinin iskelesini oluşturmaktır. Ancak, araçlarda kod iskelesi oluşturmanıza gerek duyan hiçbir şey yoktur. Örneğin, bunun yerine Mermaid kullanarak bir varlık ilişkisi diyagramının iskelesini oluşturabilirsiniz.

<#@ output extension=".md" #>
<#@ assembly name="Microsoft.EntityFrameworkCore" #>
<#@ assembly name="Microsoft.EntityFrameworkCore.Relational" #>
<#@ assembly name="Microsoft.EntityFrameworkCore.Design" #>
<#@ parameter name="Model" type="Microsoft.EntityFrameworkCore.Metadata.IModel" #>
<#@ parameter name="Options" type="Microsoft.EntityFrameworkCore.Scaffolding.ModelCodeGenerationOptions" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="Microsoft.EntityFrameworkCore" #>
# <#= Options.ContextName #>

```mermaid
erDiagram
<#
    foreach (var entityType in Model.GetEntityTypes().Where(e => !e.IsSimpleManyToManyJoinEntityType()))
    {
#>
    <#= entityType.Name #> {
    }
<#
        foreach (var foreignKey in entityType.GetForeignKeys())
        {
#>
    <#= entityType.Name #> <#= foreignKey.IsUnique ? "|" : "}" #>o--<#= foreignKey.IsRequired ? "|" : "o" #>| <#= foreignKey.PrincipalEntityType.Name #> : "<#= foreignKey.GetConstraintName() #>"
<#
        }

        foreach (var skipNavigation in entityType.GetSkipNavigations().Where(n => n.IsLeftNavigation()))
        {
#>
    <#= entityType.Name #> }o--o{ <#= skipNavigation.TargetEntityType.Name #> : <#= skipNavigation.JoinEntityType.Name #>
<#
        }
    }
#>
```