Oluşturulan Değerler

Veritabanı sütunlarının değerleri çeşitli yollarla oluşturulabilir: birincil anahtar sütunları genellikle otomatik olarak artan tamsayılardır, diğer sütunlar varsayılan veya hesaplanan değerlere sahiptir vb. Bu sayfada EF Core ile yapılandırma değeri oluşturma için çeşitli desenler ayrıntılı olarak anlatılır.

Varsayılan değerler

İlişkisel veritabanlarında bir sütun varsayılan değerle yapılandırılabilir; bir satır, bu sütun için bir değer olmadan eklenirse, varsayılan değer kullanılır.

Bir özellikte varsayılan bir değer yapılandırabilirsiniz:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.Rating)
        .HasDefaultValue(3);
}

Varsayılan değeri hesaplamak için kullanılan bir SQL parçası da belirtebilirsiniz:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.Created)
        .HasDefaultValueSql("getdate()");
}

Hesaplanan sütunlar

çoğu ilişkisel veritabanında bir sütun, değerinin veritabanında hesaplanması için yapılandırılabilir ve genellikle diğer sütunlara başvuran bir ifade kullanılır:

modelBuilder.Entity<Person>()
    .Property(p => p.DisplayName)
    .HasComputedColumnSql("[LastName] + ', ' + [FirstName]");

Yukarıdaki, değeri veritabanından her getirildiğinde hesaplanan sanal bir hesaplanan sütun oluşturur. Hesaplanan bir sütunun depolanabileceğini (bazen kalıcı olarak da adlandırılır) belirtebilirsiniz; bu da satırın her güncelleştirmesinde hesaplandığını ve normal sütunların yanı sıra diskte depolandığını da belirtebilirsiniz:

modelBuilder.Entity<Person>()
    .Property(p => p.NameLength)
    .HasComputedColumnSql("LEN([LastName]) + LEN([FirstName])", stored: true);

Birincil anahtarlar

Kural gereği, uygulama tarafından bir değer sağlanmazsa eklenen varlıklar için değerlerin oluşturulması için short, int, long veya Guid türünde bileşik olmayan birincil anahtarlar ayarlanır. Veritabanı sağlayıcınız genellikle gerekli yapılandırmayı üstlenir; örneğin, SQL Server'daki sayısal birincil anahtar otomatik olarak bir IDENTITY sütunu olacak şekilde ayarlanır.

Daha fazla bilgi için anahtarlar hakkındaki belgelere ve belirli devralma eşleme stratejilerine yönelik yönergelere bakın.

Değer oluşturmayı açıkça yapılandırma

Yukarıda EF Core'un birincil anahtarlar için değer oluşturmayı otomatik olarak ayarladığını gördük, ancak anahtar olmayan özellikler için de aynısını yapmak isteyebiliriz. Herhangi bir özelliği, eklenen varlıklar için değerinin oluşturulması için aşağıdaki gibi yapılandırabilirsiniz:

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public DateTime Inserted { get; set; }
}

Benzer şekilde, bir özellik değeri ekleme veya güncelleştirme sırasında oluşturulacak şekilde yapılandırılabilir:

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public DateTime LastUpdated { get; set; }
}

Varsayılan değerlerin veya hesaplanan sütunların aksine, değerlerin nasıl oluşturulacağını belirtmeyiz; bu, kullanılan veritabanı sağlayıcısına bağlıdır. Veritabanı sağlayıcıları bazı özellik türleri için değer oluşturmayı otomatik olarak ayarlayabilir, ancak diğerleri değerin nasıl oluşturulduğunu el ile ayarlamanızı gerektirebilir.

Örneğin, SQL Server'da bir GUID özelliği birincil anahtar olarak yapılandırıldığında sağlayıcı, en uygun sıralı GUID değerlerini oluşturmak için bir algoritma kullanarak otomatik olarak değer oluşturma istemci tarafı gerçekleştirir. Ancak, bir DateTime özelliğinde belirtmenin ValueGeneratedOnAdd hiçbir etkisi olmaz (DateTime değer oluşturma için aşağıdaki bölüme bakın).

Benzer şekilde, ekleme veya güncelleştirme sırasında oluşturulmuş olarak yapılandırılan ve eşzamanlılık belirteçleri olarak işaretlenen bayt[] özellikleri, değerlerin veritabanında otomatik olarak oluşturulması için rowversion veri türüyle ayarlanır. Ancak, belirtmenin ValueGeneratedOnAdd hiçbir etkisi yoktur.

Desteklediği belirli değer oluşturma teknikleri için sağlayıcınızın belgelerine bakın. SQL Server değer oluşturma belgelerine buradan ulaşabilirsiniz.

Tarih/saat değeri oluşturma

Sık kullanılan istek, satırın ilk eklendiği tarih/saati (eklemede oluşturulan değer) veya en son ne zaman güncelleştirildiği (ekleme veya güncelleştirmede oluşturulan değer) içeren bir veritabanı sütununa sahip olmaktır. Bunu yapmak için çeşitli stratejiler olduğundan, EF Core sağlayıcıları genellikle tarih/saat sütunları için değer oluşturmayı otomatik olarak ayarlamaz; bunu kendiniz yapılandırmanız gerekir.

Oluşturma zaman damgası

Bir tarih/saat sütununu satırın oluşturma zaman damgasına sahip olacak şekilde yapılandırmak, genellikle uygun SQL işleviyle varsayılan bir değeri yapılandırmakla ilgilidir. Örneğin, SQL Server'da aşağıdakileri kullanabilirsiniz:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.Created)
        .HasDefaultValueSql("getdate()");
}

Uygun işlevi seçtiğinizden emin olun, örneğin, çeşitli işlevler bulunabilir (örn. GETDATE() vs. GETUTCDATE()).

Güncelleştirme zaman damgası

Depolanan hesaplanan sütunlar son güncelleştirilen zaman damgalarını yönetmek için iyi bir çözüm gibi görünse de, veritabanları genellikle hesaplanan sütunda olduğu gibi GETDATE() işlevlerin belirtilmesine izin vermez. Alternatif olarak, aynı etkiyi elde etmek için bir veritabanı tetikleyicisi ayarlayabilirsiniz:

CREATE TRIGGER [dbo].[Blogs_UPDATE] ON [dbo].[Blogs]
    AFTER UPDATE
AS
BEGIN
    SET NOCOUNT ON;

    IF ((SELECT TRIGGER_NESTLEVEL()) > 1) RETURN;

    UPDATE B
    SET LastUpdated = GETDATE()
    FROM dbo.Blogs AS B
    INNER JOIN INSERTED AS I
        ON B.BlogId = I.BlogId
END

Tetikleyici oluşturma hakkında bilgi için geçişlerde ham SQL kullanma belgelerine bakın.

Değer oluşturma geçersiz kılma

Bir özellik değer oluşturma için yapılandırılmış olsa da, çoğu durumda yine de bunun için açıkça bir değer belirtebilirsiniz. Bunun gerçekten çalışıp çalışmayacağı, yapılandırılmış olan belirli bir değer oluşturma mekanizmasına bağlıdır; sütunun varsayılan değerini kullanmak yerine açık bir değer belirtebilirsiniz, ancak aynı işlem hesaplanan sütunlarla yapılamaz.

Değer oluşturmayı açık bir değerle geçersiz kılmak için, özelliği o özelliğin türü için CLR varsayılan değeri olmayan herhangi bir değere ayarlamanız yeterlidir (null için string, 0 için int, Guid.Empty vb Guid.).

Dekont

SQL Server IDENTITY'ye açık değerler ekleme denemesi varsayılan olarak başarısız olur; Geçici bir çözüm için bu belgelere bakın.

Ekleme veya güncelleştirmede oluşturulan değer olarak yapılandırılmış özellikler için açık bir değer sağlamak için, özelliği aşağıdaki gibi de yapılandırmanız gerekir:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>().Property(b => b.LastUpdated)
        .ValueGeneratedOnAddOrUpdate()
        .Metadata.SetAfterSaveBehavior(PropertySaveBehavior.Save);
}

Değer oluşturma yok

Yukarıda açıklananlar gibi belirli senaryoların dışında, özelliklerin genellikle yapılandırılmış değer oluşturması yoktur; bu, veritabanına kaydedilecek bir değerin her zaman uygulamaya ait olduğu anlamına gelir. Bu değer, bağlama eklenmeden önce yeni varlıklara atanmalıdır.

Ancak, bazı durumlarda kural tarafından ayarlanmış değer oluşturmayı devre dışı bırakmak isteyebilirsiniz. Örneğin, int türünün birincil anahtarı genellikle örtük olarak değer tarafından oluşturulan eklenti olarak yapılandırılır (örneğin, SQL Server'da kimlik sütunu). Bunu aşağıdakiler aracılığıyla devre dışı bırakabilirsiniz:

public class Blog
{
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int BlogId { get; set; }

    public string Url { get; set; }
}