Aracılığıyla paylaş


Kod İlk Ekleme, Güncelleştirme ve Silme Saklı Yordamları

Dekont

Yalnızca EF6'ya Doğru - Bu sayfada ele alınan özellikler, API'ler vb. Entity Framework 6'da sunulmuştur. Önceki bir sürümü kullanıyorsanız, bilgilerin bir kısmı veya tümü geçerli değildir.

Varsayılan olarak Code First, doğrudan tablo erişimini kullanarak ekleme, güncelleştirme ve silme komutları gerçekleştirmek için tüm varlıkları yapılandırır. EF6'dan başlayarak, Code First modelinizi modelinizdeki varlıkların bazıları veya tümü için saklı yordamları kullanacak şekilde yapılandırabilirsiniz.

Temel Varlık Eşleme

Fluent API'sini kullanarak ekleme, güncelleştirme ve silme için saklı yordamları kullanmayı tercih edebilirsiniz.

modelBuilder
  .Entity<Blog>()
  .MapToStoredProcedures();

Bunun yapılması Code First'un veritabanındaki saklı yordamların beklenen şeklini oluşturmak için bazı kuralları kullanmasına neden olur.

  • type_name_Insert, <type_name>_Update ve <type_name>>_Delete adlı <üç saklı yordam (örneğin, Blog_Insert, Blog_Update ve Blog_Delete).
  • Parametre adları özellik adlarına karşılık gelir.

    Dekont

    Belirli bir özelliğin sütununu yeniden adlandırmak için HasColumnName() veya Column özniteliğini kullanırsanız, bu ad özellik adı yerine parametreler için kullanılır.

  • Ekleme saklı yordamı , depo olarak oluşturulan (kimlik veya hesaplanan) olarak işaretlenenler dışında her özellik için bir parametreye sahip olur. Saklı yordam, depo tarafından oluşturulan her özellik için bir sütun içeren bir sonuç kümesi döndürmelidir.
  • Güncelleştirme saklı yordamı , depo tarafından oluşturulan 'Hesaplanan' deseniyle işaretlenmiş olanlar dışında her özellik için bir parametreye sahip olur. Bazı eşzamanlılık belirteçleri özgün değer için bir parametre gerektirir. Ayrıntılar için aşağıdaki Eşzamanlılık Belirteçleri bölümüne bakın. Saklı yordam, hesaplanan her özellik için bir sütun içeren bir sonuç kümesi döndürmelidir.
  • Silme saklı yordamı , varlığın anahtar değeri için bir parametreye (veya varlığın bileşik anahtarı varsa birden çok parametreye) sahip olmalıdır. Ayrıca, silme yordamının hedef tablodaki bağımsız ilişkilendirme yabancı anahtarları için de parametreleri olmalıdır (varlıkta ilgili yabancı anahtar özelliklerine sahip olmayan ilişkiler). Bazı eşzamanlılık belirteçleri özgün değer için bir parametre gerektirir. Ayrıntılar için aşağıdaki Eşzamanlılık Belirteçleri bölümüne bakın.

Örnek olarak aşağıdaki sınıfı kullanma:

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

Varsayılan saklı yordamlar:

CREATE PROCEDURE [dbo].[Blog_Insert]  
  @Name nvarchar(max),  
  @Url nvarchar(max)  
AS  
BEGIN
  INSERT INTO [dbo].[Blogs] ([Name], [Url])
  VALUES (@Name, @Url)

  SELECT SCOPE_IDENTITY() AS BlogId
END
CREATE PROCEDURE [dbo].[Blog_Update]  
  @BlogId int,  
  @Name nvarchar(max),  
  @Url nvarchar(max)  
AS  
  UPDATE [dbo].[Blogs]
  SET [Name] = @Name, [Url] = @Url     
  WHERE BlogId = @BlogId;
CREATE PROCEDURE [dbo].[Blog_Delete]  
  @BlogId int  
AS  
  DELETE FROM [dbo].[Blogs]
  WHERE BlogId = @BlogId

Varsayılanları Geçersiz Kılma

Varsayılan olarak yapılandırılanların bir bölümünü veya tümünü geçersiz kılabilirsiniz.

Bir veya daha fazla saklı yordamın adını değiştirebilirsiniz. Bu örnek yalnızca güncelleştirme saklı yordamını yeniden adlandırır.

modelBuilder  
  .Entity<Blog>()  
  .MapToStoredProcedures(s =>  
    s.Update(u => u.HasName("modify_blog")));

Bu örnek, saklı üç yordamın tümünü yeniden adlandırır.

modelBuilder  
  .Entity<Blog>()  
  .MapToStoredProcedures(s =>  
    s.Update(u => u.HasName("modify_blog"))  
     .Delete(d => d.HasName("delete_blog"))  
     .Insert(i => i.HasName("insert_blog")));

Bu örneklerde çağrılar birbirine zincirlenmiştir, ancak lambda bloğu söz dizimini de kullanabilirsiniz.

modelBuilder  
  .Entity<Blog>()  
  .MapToStoredProcedures(s =>  
    {  
      s.Update(u => u.HasName("modify_blog"));  
      s.Delete(d => d.HasName("delete_blog"));  
      s.Insert(i => i.HasName("insert_blog"));  
    });

Bu örnek, güncelleştirme saklı yordamındaki BlogId özelliğinin parametresini yeniden adlandırır.

modelBuilder  
  .Entity<Blog>()  
  .MapToStoredProcedures(s =>  
    s.Update(u => u.Parameter(b => b.BlogId, "blog_id")));

Bu çağrıların tümü zincirlenebilir ve birleştirilebilir. Burada, üç saklı yordamı ve parametrelerini yeniden adlandıran bir örnek verilmiştir.

modelBuilder  
  .Entity<Blog>()  
  .MapToStoredProcedures(s =>  
    s.Update(u => u.HasName("modify_blog")  
                   .Parameter(b => b.BlogId, "blog_id")  
                   .Parameter(b => b.Name, "blog_name")  
                   .Parameter(b => b.Url, "blog_url"))  
     .Delete(d => d.HasName("delete_blog")  
                   .Parameter(b => b.BlogId, "blog_id"))  
     .Insert(i => i.HasName("insert_blog")  
                   .Parameter(b => b.Name, "blog_name")  
                   .Parameter(b => b.Url, "blog_url")));

Veritabanı tarafından oluşturulan değerleri içeren sonuç kümesindeki sütunların adını da değiştirebilirsiniz.

modelBuilder
  .Entity<Blog>()
  .MapToStoredProcedures(s =>
    s.Insert(i => i.Result(b => b.BlogId, "generated_blog_identity")));
CREATE PROCEDURE [dbo].[Blog_Insert]  
  @Name nvarchar(max),  
  @Url nvarchar(max)  
AS  
BEGIN
  INSERT INTO [dbo].[Blogs] ([Name], [Url])
  VALUES (@Name, @Url)

  SELECT SCOPE_IDENTITY() AS generated_blog_id
END

Sınıfında Yabancı Anahtar Olmayan İlişkiler (Bağımsız İlişkilendirmeler)

Sınıf tanımına yabancı anahtar özelliği eklendiğinde, ilgili parametre diğer tüm özelliklerle aynı şekilde yeniden adlandırılabilir. Sınıfında yabancı anahtar özelliği olmayan bir ilişki varsa, varsayılan parametre adı <navigation_property_name>_<primary_key_name> olur.

Örneğin, aşağıdaki sınıf tanımları, Saklı yordamlarda Post ekleme ve güncelleştirme için bir Blog_BlogId parametresinin beklenmesine neden olur.

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

  public List<Post> Posts { get; set; }  
}  

public class Post  
{  
  public int PostId { get; set; }  
  public string Title { get; set; }  
  public string Content { get; set; }  

  public Blog Blog { get; set; }  
}

Varsayılanları Geçersiz Kılma

Parameter yönteminin birincil anahtar özelliğinin yolunu sağlayarak sınıfına dahil edilmeyen yabancı anahtarların parametrelerini değiştirebilirsiniz.

modelBuilder
  .Entity<Post>()  
  .MapToStoredProcedures(s =>  
    s.Insert(i => i.Parameter(p => p.Blog.BlogId, "blog_id")));

Bağımlı varlıkta (Post.Blog özelliği yok) gezinti özelliğine sahip değilseniz İlişkilendirme yöntemini kullanarak ilişkinin diğer ucunu tanımlayabilir ve ardından anahtar özelliklerin her birine karşılık gelen parametreleri yapılandırabilirsiniz.

modelBuilder
  .Entity<Post>()  
  .MapToStoredProcedures(s =>  
    s.Insert(i => i.Navigation<Blog>(  
      b => b.Posts,  
      c => c.Parameter(b => b.BlogId, "blog_id"))));

Eşzamanlılık Belirteçleri

Saklı yordamları güncelleştirme ve silme işlemlerinin eşzamanlılık ile de ilgilenmesi gerekebilir:

  • Varlık eşzamanlılık belirteçleri içeriyorsa, saklı yordam isteğe bağlı olarak güncelleştirilen/silinen satır sayısını (etkilenen satırlar) döndüren bir çıkış parametresine sahip olabilir. Böyle bir parametre RowsAffectedParameter yöntemi kullanılarak yapılandırılmalıdır.
    VARSAYıLAN olarak EF, kaç satırın etkilendiğini belirlemek için ExecuteNonQuery'den dönüş değerini kullanır. Sproc'unuzda yürütmenin sonunda ExecuteNonQuery'nin dönüş değerinin yanlış olmasına (EF'nin perspektifinden) neden olacak herhangi bir mantık gerçekleştirirseniz, etkilenen bir çıkış parametresinin belirtilmesi yararlı olur.
  • Her eşzamanlılık belirteci için property_name>_Original (örneğin, Timestamp_Original ) adlı <bir parametre olacaktır. Bu, veritabanından sorgulandığında değeri olan bu özelliğin özgün değeri geçirilir.
    • Veritabanı tarafından hesaplanan eşzamanlılık belirteçleri (zaman damgaları gibi) yalnızca özgün bir değer parametresine sahip olur.
    • Eşzamanlılık belirteçleri olarak ayarlanan hesaplanmamış özellikler, güncelleştirme yordamındaki yeni değer için bir parametreye de sahip olur. Bu, yeni değerler için önceden açıklanan adlandırma kurallarını kullanır. Bu tür bir belirtecin örneği, eşzamanlılık belirteci olarak Blog'un URL'sini kullanmak olabilir. Bu, kodunuz tarafından yeni bir değere güncelleştirilebildiğinden (yalnızca veritabanı tarafından güncelleştirilen Bir Zaman Damgası belirtecinin aksine) yeni değer gereklidir.

Bu örnek bir sınıftır ve saklı yordamı zaman damgası eşzamanlılık belirteci ile güncelleştirir.

public class Blog  
{  
  public int BlogId { get; set; }  
  public string Name { get; set; }  
  public string Url { get; set; }  
  [Timestamp]
  public byte[] Timestamp { get; set; }
}
CREATE PROCEDURE [dbo].[Blog_Update]  
  @BlogId int,  
  @Name nvarchar(max),  
  @Url nvarchar(max),
  @Timestamp_Original rowversion  
AS  
  UPDATE [dbo].[Blogs]
  SET [Name] = @Name, [Url] = @Url     
  WHERE BlogId = @BlogId AND [Timestamp] = @Timestamp_Original

Burada örnek bir sınıf ve hesaplanmamış eşzamanlılık belirteci ile saklı yordamı güncelleştirin.

public class Blog  
{  
  public int BlogId { get; set; }  
  public string Name { get; set; }  
  [ConcurrencyCheck]
  public string Url { get; set; }  
}
CREATE PROCEDURE [dbo].[Blog_Update]  
  @BlogId int,  
  @Name nvarchar(max),  
  @Url nvarchar(max),
  @Url_Original nvarchar(max),
AS  
  UPDATE [dbo].[Blogs]
  SET [Name] = @Name, [Url] = @Url     
  WHERE BlogId = @BlogId AND [Url] = @Url_Original

Varsayılanları Geçersiz Kılma

İsteğe bağlı olarak, etkilenen bir satır parametresini tanıtabilirsiniz.

modelBuilder  
  .Entity<Blog>()  
  .MapToStoredProcedures(s =>  
    s.Update(u => u.RowsAffectedParameter("rows_affected")));

Yalnızca özgün değerin geçirildiği veritabanı hesaplanan eşzamanlılık belirteçleri için, özgün değerin parametresini yeniden adlandırmak için standart parametre yeniden adlandırma mekanizmasını kullanabilirsiniz.

modelBuilder  
  .Entity<Blog>()  
  .MapToStoredProcedures(s =>  
    s.Update(u => u.Parameter(b => b.Timestamp, "blog_timestamp")));

Hem özgün hem de yeni değerin geçirildiği hesaplanmamış eşzamanlılık belirteçleri için, her parametre için bir ad sağlamanıza olanak tanıyan bir Parametre aşırı yüklemesini kullanabilirsiniz.

modelBuilder
 .Entity<Blog>()
 .MapToStoredProcedures(s => s.Update(u => u.Parameter(b => b.Url, "blog_url", "blog_original_url")));

Çoktan Çoğa İlişkiler

Bu bölümde örnek olarak aşağıdaki sınıfları kullanacağız.

public class Post  
{  
  public int PostId { get; set; }  
  public string Title { get; set; }  
  public string Content { get; set; }  

  public List<Tag> Tags { get; set; }  
}  

public class Tag  
{  
  public int TagId { get; set; }  
  public string TagName { get; set; }  

  public List<Post> Posts { get; set; }  
}

Çoka çok ilişkiler, aşağıdaki söz dizimiyle saklı yordamlara eşlenebilir.

modelBuilder  
  .Entity<Post>()  
  .HasMany(p => p.Tags)  
  .WithMany(t => t.Posts)  
  .MapToStoredProcedures();

Başka bir yapılandırma sağlanmazsa, varsayılan olarak aşağıdaki saklı yordam şekli kullanılır.

  • type_one type_two>><_Insert ve< type_one type_two>><_Delete adlı <iki saklı yordam (örneğin, PostTag_Insert ve PostTag_Delete).
  • Parametreler, her tür için anahtar değerleri olacaktır. type_name_<property_name>> olan <her parametrenin adı (örneğin, Post_PostId ve Tag_TagId).

Aşağıda örnek ekleme ve güncelleştirme saklı yordamları verilmiştir.

CREATE PROCEDURE [dbo].[PostTag_Insert]  
  @Post_PostId int,  
  @Tag_TagId int  
AS  
  INSERT INTO [dbo].[Post_Tags] (Post_PostId, Tag_TagId)   
  VALUES (@Post_PostId, @Tag_TagId)
CREATE PROCEDURE [dbo].[PostTag_Delete]  
  @Post_PostId int,  
  @Tag_TagId int  
AS  
  DELETE FROM [dbo].[Post_Tags]    
  WHERE Post_PostId = @Post_PostId AND Tag_TagId = @Tag_TagId

Varsayılanları Geçersiz Kılma

Yordam ve parametre adları varlık saklı yordamlarına benzer şekilde yapılandırılabilir.

modelBuilder  
  .Entity<Post>()  
  .HasMany(p => p.Tags)  
  .WithMany(t => t.Posts)  
  .MapToStoredProcedures(s =>  
    s.Insert(i => i.HasName("add_post_tag")  
                   .LeftKeyParameter(p => p.PostId, "post_id")  
                   .RightKeyParameter(t => t.TagId, "tag_id"))  
     .Delete(d => d.HasName("remove_post_tag")  
                   .LeftKeyParameter(p => p.PostId, "post_id")  
                   .RightKeyParameter(t => t.TagId, "tag_id")));