Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Tersine mühendislik, varlık türü sınıflarını ve veritabanı şemasını temel alan bir DbContext sınıfını iskeleleme işlemidir. EF Core Paket Yöneticisi Konsolu (PMC) araçlarının Scaffold-DbContext komutu veya .NET Komut Satırı Arabirimi (CLI) araçlarının dotnet ef dbcontext scaffold komutu kullanılarak gerçekleştirilebilir.
Note
Burada belgelenen DbContext ve varlık türlerinin iskelet oluşturması, Visual Studio kullanarak ASP.NET Core'daki denetleyicilerin iskelet oluşturmasından farklıdır ve bu burada belgelenmemiştir.
Tip
Visual Studio kullanıyorsanız EF Core Power Tools topluluk uzantısını deneyin. Bu araçlar, EF Core komut satırı araçlarının üzerine inşa edilen ve ek iş akışı ve özelleştirme seçenekleri sunan bir grafik aracı sağlar.
Prerequisites
- İskele oluşturmadan önce, yalnızca Visual Studio üzerinde çalışan PMC araçlarını veya .NET tarafından desteklenen tüm platformlarda çalışan .NET CLI araçlarını yüklemeniz gerekir.
- Hazırladığınız projede
Microsoft.EntityFrameworkCore.Designiçin NuGet paketini yükleyin. - yapı iskelesi oluşturmak istediğiniz veritabanı şemasını hedefleyen veritabanı sağlayıcısı için NuGet paketini yükleyin.
Gerekli bağımsız değişkenler
Hem PMC hem de .NET CLI komutlarının iki gerekli bağımsız değişkeni vardır: veritabanına bağlantı dizesi ve kullanılacak EF Core veritabanı sağlayıcısı.
Bağlantı dizesi
Warning
Bu makalede, kullanıcının kimliğinin doğrulanması gerekmeyen bir yerel veritabanı kullanılır. Üretim uygulamaları kullanılabilir en güvenli kimlik doğrulama akışını kullanmalıdır. Dağıtılan test ve üretim uygulamaları için kimlik doğrulaması hakkında daha fazla bilgi için bkz . Güvenli kimlik doğrulama akışları.
Komutun ilk bağımsız değişkeni, veritabanına bir bağlantı dizesidir. Araçlar, veritabanı şemasını okumak için bu bağlantı dizesi kullanır.
Bağlantı dizesinin nasıl tırnak içine alınacağı ve kaçış karakterleriyle işlendiği, komutu çalıştırmak için kullanılan kabuğa bağlıdır. Kabuk dokümantasyonuna başvurun. Örneğin, PowerShell'de $ için kaçış gereklidir, ancak \ için gerekli değildir.
Aşağıdaki örnek, makinenin SQL Server LocalDB örneğinde bulunan DbContext veritabanından varlık türleri ve Chinook için Microsoft.EntityFrameworkCore.SqlServer veritabanı sağlayıcısını kullanan bir yapı iskelesi oluşturur.
dotnet ef dbcontext scaffold "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=Chinook" Microsoft.EntityFrameworkCore.SqlServer
Tip
Yapılandırmayı kullanarak bağlantı dizesini alabilir ve depolayabilirsiniz
İskeleli koddaki bağlantı dizeleri
Varsayılan olarak, yapı iskelesi, kodda bağlantı dizesini dahil eder, ancak bir uyarı ile birlikte. Örneğin:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263.
=> optionsBuilder.UseSqlServer("Data Source=(LocalDb)\\MSSQLLocalDB;Database=AllTogetherNow");
Bu, oluşturulan kodun ilk kullanıldığında kilitlenmemesi için yapılır ve bu çok kötü bir öğrenme deneyimi olacaktır. Ancak uyarının dediği gibi bağlantı dizesi üretim kodunda bulunmamalıdır. Bağlantı dizelerinin nasıl yönetilebileceği konusunda DbContext Yaşam Süresi, Yapılandırma ve Başlatma bölümüne bakın.
Tip
-NoOnConfiguring bağlantı dizesi içeren yöntemin --no-onconfiguring oluşturulmasını engellemek için (Visual Studio PMC) veya OnConfiguring (.NET CLI) seçeneği geçirilebilir.
Sağlayıcı adı
İkinci bağımsız değişken, sağlayıcı adıdır. Sağlayıcı adı, genellikle sağlayıcının NuGet paket adıyla aynıdır. Örneğin, SQL Server veya Azure SQL için kullanın Microsoft.EntityFrameworkCore.SqlServer.
Komut satırı seçenekleri
yapı iskelesi işlemi çeşitli komut satırı seçenekleriyle denetlenebilir.
Tabloları ve görünümleri belirtme
Varsayılan olarak, veritabanı şemasındaki tüm tablolar ve görünümler varlık türleri olarak oluşturulur. Şemaları ve tabloları belirterek tabloların ve görünümlerin oluşturulmasını sınırlayabilirsiniz.
-Schemas (Visual Studio PMC) veya --schema (.NET CLI) bağımsız değişkeni, varlık türlerinin oluşturulacağı tablo ve görünümlerin şemalarını belirtir. Bu bağımsız değişken atlanırsa, tüm şemalar dahil edilir. Bu seçenek kullanılırsa, veya -Tableskullanılarak --table açıkça dahil edilmeseler bile şemalardaki tüm tablolar ve görünümler modele dahil edilir.
Varlık türlerinin oluşturulacağı tabloları ve görünümleri, -Tables (Visual Studio PMC) veya --table (.NET CLI) bağımsız değişkeni belirler. Belirli bir şemadaki tablolar veya görünümler 'schema.table' veya 'schema.view' biçimi kullanılarak eklenebilir. Bu seçenek atlanırsa, tüm tablolar ve görünümler eklenir. |
Örneğin, yalnızca Artists ve Albums tablolarının iskeleti oluşturmak için:
dotnet ef dbcontext scaffold ... --table Artist --table Album
Customer ve Contractor şemalarından tüm tabloları ve görünümleri oluşturmak için:
dotnet ef dbcontext scaffold ... --schema Customer --schema Contractor
Örneğin, Purchases şemasından Customer tablosunu ve Accounts şemasından Contracts ve Contractor tablolarını oluşturmak için:
dotnet ef dbcontext scaffold ... --table Customer.Purchases --table Contractor.Accounts --table Contractor.Contracts
Veritabanı adlarını koruma
Tablo ve sütun adları, tür ve özellikler için, varsayılan olarak .NET adlandırma kurallarıyla daha iyi eşleşecek şekilde düzeltilir. (Visual Studio PMC) veya -UseDatabaseNames (.NET CLI) belirtilmesi --use-database-names , özgün veritabanı adlarını olabildiğince koruyarak bu davranışı devre dışı bırakır. Geçersiz .NET tanımlayıcıları düzeltilmeye devam eder ve gezinti özellikleri gibi sentezlenmiş adlar .NET adlandırma kurallarına uymaya devam eder.
Ters mühendislik uygulanmış modellerin iskelesini oluştururken çoğullaştırıcıyı devre dışı bırakmak için -NoPluralize (Visual Studio PMC) veya --no-pluralize (.NET CLI) kullanın.
Örneğin, aşağıdaki tabloları göz önünde bulundurun:
CREATE TABLE [BLOGS] (
[ID] int NOT NULL IDENTITY,
[Blog_Name] nvarchar(max) NOT NULL,
CONSTRAINT [PK_Blogs] PRIMARY KEY ([ID]));
CREATE TABLE [posts] (
[id] int NOT NULL IDENTITY,
[postTitle] nvarchar(max) NOT NULL,
[post content] nvarchar(max) NOT NULL,
[1 PublishedON] datetime2 NOT NULL,
[2 DeletedON] datetime2 NULL,
[BlogID] int NOT NULL,
CONSTRAINT [PK_Posts] PRIMARY KEY ([id]),
CONSTRAINT [FK_Posts_Blogs_BlogId] FOREIGN KEY ([BlogID]) REFERENCES [Blogs] ([ID]) ON DELETE CASCADE);
Varsayılan olarak, aşağıdaki varlık türleri bu tablolardan otomatik olarak oluşturulacaktır.
public partial class Blog
{
public int Id { get; set; }
public string BlogName { get; set; } = null!;
public virtual ICollection<Post> Posts { get; set; } = new List<Post>();
}
public partial class Post
{
public int Id { get; set; }
public string PostTitle { get; set; } = null!;
public string PostContent { get; set; } = null!;
public DateTime _1PublishedOn { get; set; }
public DateTime? _2DeletedOn { get; set; }
public int BlogId { get; set; }
public virtual Blog Blog { get; set; } = null!;
public virtual ICollection<Tag> Tags { get; set; } = new List<Tag>();
}
Ancak, -UseDatabaseNames veya --use-database-names kullanıldığında, şu varlık türlerine yol açar:
public partial class BLOG
{
public int ID { get; set; }
public string Blog_Name { get; set; } = null!;
public virtual ICollection<post> posts { get; set; } = new List<post>();
}
public partial class post
{
public int id { get; set; }
public string postTitle { get; set; } = null!;
public string post_content { get; set; } = null!;
public DateTime _1_PublishedON { get; set; }
public DateTime? _2_DeletedON { get; set; }
public int BlogID { get; set; }
public virtual BLOG Blog { get; set; } = null!;
}
Eşleme özniteliklerini kullanma (diğer adıyla Veri Ek Açıklamaları)
Varlık türleri varsayılan olarak ModelBuilder API içindeki OnModelCreating yapılandırılır.
-DataAnnotations (PMC) veya --data-annotations (.NET CLI) belirtin ve mümkün olduğunda eşleme özniteliklerini kullanın.
Örneğin, Fluent API'sinin kullanılması şu yapı iskelesini oluşturur:
entity.Property(e => e.Title)
.IsRequired()
.HasMaxLength(160);
Veri Ek Açıklamaları kullanılırken bu yapı iskelesi oluşturulur:
[Required]
[StringLength(160)]
public string Title { get; set; }
Tip
Modelin bazı yönleri eşleme öznitelikleri kullanılarak yapılandırılamaz. İskeleyici, bu durumları işlemek için model oluşturma API'sini hâlâ kullanmaya devam edecek.
DbContext adı
Oluşturulan DbContext sınıf adı, varsayılan olarak veritabanı adına Context eki eklenerek oluşturulur. Farklı bir tane belirtmek için, -Context PMC'de ve --context .NET CLI'da kullanın.
Hedef dizinler ve ad alanları
Varlık sınıfları ve DbContext sınıfı, projenin kök dizinine hazırlanır ve projenin varsayılan ad alanı kullanılarak oluşturuldu.
--output-dir kullanarak sınıfların oluşturulduğu dizini belirtebilirsiniz ve --context-dir, DbContext sınıfını varlık türü sınıflarından ayrı bir dizine yapı iskelesi oluşturmak için kullanılabilir:
dotnet ef dbcontext scaffold ... --context-dir Data --output-dir Models
Varsayılan olarak, ad alanı, kök ad alanına ek olarak projenin kök dizini altındaki alt dizinlerin adlarını içerir. Ancak, --namespace kullanarak tüm çıktı sınıfları için ad alanını geçersiz kılabilirsiniz. Ayrıca --context-namespace kullanarak, yalnızca DbContext sınıfı için ad alanını geçersiz kılabilirsiniz:
dotnet ef dbcontext scaffold ... --namespace Your.Namespace --context-namespace Your.DbContext.Namespace
iskele kod
Mevcut bir veritabanından yapı iskelesi oluşturmanın sonucu şudur:
-
DbContextsınıfından devralan bir sınıf içeren dosya - Her varlık türü için bir dosya
Tip
EF7'den başlayarak, oluşturulan kodu özelleştirmek için T4 metin şablonlarını da kullanabilirsiniz. Daha fazla ayrıntı için bkz. Özel Tersine Mühendislik Şablonları.
C# Null yapılabilir başvuru türleri
İskele, C# null atanabilir başvuru türlerini (NRT'ler) kullanan EF modeli ve varlık türleri oluşturabilir. NRT kullanımı, NRT desteği etkinleştirildiğinde kodun oluşturulduğu C# projesinde otomatik olarak yapılandırılır.
Örneğin, aşağıdaki Tags tabloda hem null değer atanabilir hem de boş değer atanamayan dize sütunları yer alır:
CREATE TABLE [Tags] (
[Id] int NOT NULL IDENTITY,
[Name] nvarchar(max) NOT NULL,
[Description] nvarchar(max) NULL,
CONSTRAINT [PK_Tags] PRIMARY KEY ([Id]));
Bu, oluşturulan sınıfta karşılık gelen null atanabilir ve null atanamaz dize özelliklerine neden olur:
public partial class Tag
{
public Tag()
{
Posts = new HashSet<Post>();
}
public int Id { get; set; }
public string Name { get; set; } = null!;
public string? Description { get; set; }
public virtual ICollection<Post> Posts { get; set; }
}
Benzer şekilde, aşağıdaki Posts tablo, Blogs tablosuyla gerekli bir ilişki içerir.
CREATE TABLE [Posts] (
[Id] int NOT NULL IDENTITY,
[Title] nvarchar(max) NOT NULL,
[Contents] nvarchar(max) NOT NULL,
[PostedOn] datetime2 NOT NULL,
[UpdatedOn] datetime2 NULL,
[BlogId] int NOT NULL,
CONSTRAINT [PK_Posts] PRIMARY KEY ([Id]),
CONSTRAINT [FK_Posts_Blogs_BlogId] FOREIGN KEY ([BlogId]) REFERENCES [Blogs] ([Id]));
Bu, bloglar arasında null kabul etmeyen (gerekli) ilişkilerin çerçevesini oluşturur.
public partial class Blog
{
public Blog()
{
Posts = new HashSet<Post>();
}
public int Id { get; set; }
public string Name { get; set; } = null!;
public virtual ICollection<Post> Posts { get; set; }
}
Ve gönderiler:
public partial class Post
{
public Post()
{
Tags = new HashSet<Tag>();
}
public int Id { get; set; }
public string Title { get; set; } = null!;
public string Contents { get; set; } = null!;
public DateTime PostedOn { get; set; }
public DateTime? UpdatedOn { get; set; }
public int BlogId { get; set; }
public virtual Blog Blog { get; set; } = null!;
public virtual ICollection<Tag> Tags { get; set; }
}
Çok-a-çok ilişkiler
İskeleleme süreci, basit birleştirme tablolarını algılar ve bunlar için otomatik olarak çoka çok eşleme oluşturur. Örneğin, Posts ve Tags tablolarını ve bunları bağlayan birleştirme tablosu PostTag göz önünde bulundurun.
CREATE TABLE [Tags] (
[Id] int NOT NULL IDENTITY,
[Name] nvarchar(max) NOT NULL,
[Description] nvarchar(max) NULL,
CONSTRAINT [PK_Tags] PRIMARY KEY ([Id]));
CREATE TABLE [Posts] (
[Id] int NOT NULL IDENTITY,
[Title] nvarchar(max) NOT NULL,
[Contents] nvarchar(max) NOT NULL,
[PostedOn] datetime2 NOT NULL,
[UpdatedOn] datetime2 NULL,
CONSTRAINT [PK_Posts] PRIMARY KEY ([Id]));
CREATE TABLE [PostTag] (
[PostsId] int NOT NULL,
[TagsId] int NOT NULL,
CONSTRAINT [PK_PostTag] PRIMARY KEY ([PostsId], [TagsId]),
CONSTRAINT [FK_PostTag_Posts_TagsId] FOREIGN KEY ([TagsId]) REFERENCES [Tags] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_PostTag_Tags_PostsId] FOREIGN KEY ([PostsId]) REFERENCES [Posts] ([Id]) ON DELETE CASCADE);
yapılandırıldığında, bu Post için bir sınıf oluşturur:
public partial class Post
{
public Post()
{
Tags = new HashSet<Tag>();
}
public int Id { get; set; }
public string Title { get; set; } = null!;
public string Contents { get; set; } = null!;
public DateTime PostedOn { get; set; }
public DateTime? UpdatedOn { get; set; }
public int BlogId { get; set; }
public virtual Blog Blog { get; set; } = null!;
public virtual ICollection<Tag> Tags { get; set; }
}
Tag için de bir sınıf:
public partial class Tag
{
public Tag()
{
Posts = new HashSet<Post>();
}
public int Id { get; set; }
public string Name { get; set; } = null!;
public string? Description { get; set; }
public virtual ICollection<Post> Posts { get; set; }
}
Ama tablo için PostTag sınıf yok. Bunun yerine, (çoka çok) ilişki için yapılandırma otomatik oluşturulur.
entity.HasMany(d => d.Tags)
.WithMany(p => p.Posts)
.UsingEntity<Dictionary<string, object>>(
"PostTag",
r => r.HasOne<Tag>().WithMany().HasForeignKey("TagsId"),
l => l.HasOne<Post>().WithMany().HasForeignKey("PostsId"),
j =>
{
j.HasKey("PostsId", "TagsId");
j.ToTable("PostTag");
j.HasIndex(new[] { "TagsId" }, "IX_PostTag_TagsId");
});
Diğer programlama dilleri
Microsoft tarafından yayımlanan EF Core paketleri C# kodunun iskelesini oluşturur. Ancak, altta yatan yapı iskelesi sistemi, diğer dillere iskele oluşturmayı sağlayan bir eklenti modelinin desteğini içerir. Bu eklenti modeli, topluluk tarafından çalıştırılan çeşitli projeler tarafından kullanılır, örneğin:
- EntityFrameworkCore.VisualBasic , Visual Basic için destek sağlar
- EFCore.FSharp , F için destek sağlar#
Kodu özelleştirme
EF7'den başlayarak, oluşturulan kodu özelleştirmenin en iyi yollarından biri, kodu oluşturmak için kullanılan T4 şablonlarını özelleştirmektir.
Kod oluşturulduktan sonra da değiştirilebilir, ancak bunu yapmak için en iyi yol, veritabanı modeli değiştiğinde iskele işlemini yeniden çalıştırmayı isteyip istemediğinize bağlıdır.
iskelet yalnızca bir kez
Bu yaklaşımla, kılavuz kod gelecekte kod tabanlı haritalama için bir başlangıç noktası sağlar. Oluşturulan kodda herhangi bir değişiklik istendiği gibi yapılabilir; projenizdeki diğer kodlarda olduğu gibi normal bir kod haline gelir.
Veritabanını ve EF modelini eşitlenmiş durumda tutmak iki yoldan biriyle yapılabilir:
- EF Core veritabanı geçişlerini kullanmaya geçin ve şemayı yönlendirmek için varlık türlerini ve EF model yapılandırmasını doğruluk kaynağı olarak kullanarak geçişleri uygulayın.
- Veritabanı değiştiğinde varlık türlerini ve EF yapılandırmasını el ile güncelleştirin. Örneğin, tabloya yeni bir sütun eklenirse, eşlenen varlık türüne sütun için bir özellik ekleyin ve içindeki eşleme özniteliklerini ve/veya kodu
OnModelCreatingkullanarak gerekli yapılandırmaları ekleyin. Bu oldukça kolaydır ve tek gerçek zorluk, veritabanı değişikliklerinin bir şekilde kaydedildiğinden veya algılandığından emin olmak ve koddan sorumlu geliştiricilerin tepki gösterebilmesini sağlamaktır.
Yinelenen yapı iskeleti
Bir kez yapı iskelesi oluşturmanın alternatif bir yaklaşımı, veritabanı her değiştiğinde yeniden iskele oluşturmaktır. Bu, önceden oluşturulan kodun üzerine yazacaktır, yani bu koddaki varlık türleri veya EF yapılandırması üzerinde yapılan tüm değişiklikler kaybolur.
[İPUCU] Varsayılan olarak, EF komutları yanlışlıkla kod kaybına karşı korumak için mevcut kodun üzerine yazmaz.
-Force(Visual Studio PMC) veya--force(.NET CLI) bağımsız değişkeni, mevcut dosyaların üzerine yazmaya zorlamak için kullanılabilir.
iskelenmiş kodun üzerine yazılacağından, doğrudan değiştirmemek, bunun yerine kısmi sınıflar ve yöntemlere ve EF Core'da yapılandırmanın geçersiz kılınmasına izin veren mekanizmalara güvenmek en iyisidir. Specifically:
-
DbContextHem sınıf hem de varlık sınıfları kısmi olarak oluşturulur. Bu, yapı iskelesi çalıştırıldığında geçersiz kılınmayacak ayrı bir dosyaya ek üyeler ve kodlar eklenmesine olanak tanır. -
DbContextsınıfı adlıOnModelCreatingPartialkısmi bir yöntem içerir. Bu yöntemin bir uygulaması,DbContextiçin kısmi sınıfa eklenebilir.OnModelCreatingçağrıldıktan sonra o çağrılacaktır. - API'ler kullanılarak
ModelBuilderyapılan model yapılandırması, kurallar veya eşleme öznitelikleri tarafından yapılan tüm yapılandırmaların yanı sıra model oluşturucuda yapılan daha önceki yapılandırmaları geçersiz kılar. Bu,OnModelCreatingPartialkodunun, iskele süreciyle oluşturulan yapılandırmayı kaldırmaya gerek kalmadan geçersiz kılmak için kullanılabileceği anlamına gelir.
Son olarak, EF7'den başlayarak kod oluşturmak için kullanılan T4 şablonlarının özelleştirilebileceğini unutmayın. Bu, genellikle varsayılanlarla iskele oluşturmaktan ve ardından kısmi sınıflar ve/veya yöntemlerle değişiklik yapmaktan daha etkili bir yaklaşımdır.
Nasıl çalışır?
Tersine mühendislik, veritabanı şemasını okuyarak başlar. Tablolar, sütunlar, kısıtlamalar ve dizinler hakkındaki bilgileri okur.
Ardından, bir EF Core modeli oluşturmak için şema bilgilerini kullanır. Tablolar varlık türleri oluşturmak için, sütunlar özellik oluşturmak için ve yabancı anahtarlar ilişki oluşturmak için kullanılır.
Son olarak, model, kod oluşturmak için kullanılır. Uygulamanızdan aynı modeli yeniden oluşturmak için varlık türü sınıfları, Fluent API ve veri notları üretilir.
Limitations
- Bir modelle ilgili her şey, bir veritabanı şeması kullanılarak temsil edilemez. Örneğin, devralma hiyerarşileri, sahip olunan türler ve tablo bölme hakkındaki bilgiler veritabanı şemasında mevcut değildir. Bu nedenle, bu yapılar hiçbir zaman yapı iskelesi kurulmayacak.
- Ayrıca, bazı sütun türleri EF Core sağlayıcısı tarafından desteklenmeyebilir. Bu sütunlar modele dahil edilmeyecektir.
- İki kullanıcının aynı varlığı aynı anda güncelleştirmesini önlemek için EF Core modelinde eşzamanlılık belirteçleri tanımlayabilirsiniz. Bazı veritabanlarında bu tür bir sütunu (örneğin, SQL Server'da rowversion) temsil eden özel bir tür vardır; bu durumda, bu bilgilerin tersine mühendisliği yapılabilir; ancak, diğer eşzamanlılık belirteçleri iskele edilmeyecektir.