2012-06-27 11 views
7

Aşağıdaki koda benzer bir düzende yazılmış bir DAL nesnesi ile çalışıyorum. Kurulumu göstermek için çok fazla kod kodunu sadeleştirdim.SqlConnection, SqlDataAdapter ve SqlCommand nesnelerini yeniden kullanmanız gerekir mi?

public class UserDatabase : IDisposable 
{ 
    private SqlDataAdapter UserDbAdapter; 
    private SqlCommand UserSelectCommand; 
    private SqlCommand UserInsertCommand; 
    private SqlCommand UserUpdateCommand; 
    private SqlCommand UserDeleteCommand; 

    private System.Data.SqlClient.SqlConnection SQLConnection; 

    public UserDatabase() 
    { 
     this.SQLConnection = new System.Data.SqlClient.SqlConnection(ConnectionString); 
     this.UserDbAdapter= new SqlDataAdapter(); 
     this.UserDbAdapter.DeleteCommand = this.UserDeleteCommand; 
     this.UserDbAdapter.InsertCommand = this.UserInsertCommand; 
     this.UserDbAdapter.SelectCommand = this.UserSelectCommand; 
     this.UserDbAdapter.UpdateCommand = this.UserUpdateCommand; 
    } 

    private bool FillUsers(DataSet UserDataSet, out int numberOfRecords) 
    { 
     bool success = true; 

     numberOfRecords = 0; 
     string errorMsg = null; 

     this.UserDbAdapter.SelectCommand = this.GetUsersSelectCommand(); 

     numberOfRecords = UserDbAdapter.Fill(UserDataSet, UsersTableName); 

     return success; 
    } 

    private SqlCommand GetUserSelectCommand() 
    { 
     if (this.UserSelectCommand==null) 
      this.UserSelectCommand= new System.Data.SqlClient.SqlCommand(); 
     this.UserSelectCommand.CommandText = "dbo.Users_Select"; 
     this.UserSelectCommand.CommandType = System.Data.CommandType.StoredProcedure; 
     this.UserSelectCommand.Connection = this.SQLConnection; 
     this.UserSelectCommand.Parameters.Clear(); 
     this.UserSelectCommand.Parameters.AddRange(new System.Data.SqlClient.SqlParameter[] { 
     new System.Data.SqlClient.SqlParameter("@RETURN_VALUE", System.Data.SqlDbType.Variant, 0, System.Data.ParameterDirection.ReturnValue, false, ((byte)(0)), ((byte)(0)), "", System.Data.DataRowVersion.Current, null)}); 

     return UserSelectCommand; 
    } 

Bağlantı nesnesi, SqlCommands ve SqlDataAdapter yeniden aynı şekilde yazılır birden diğer Dolgu tipi işlevleri vardır. SqlDataAdapter, SqlConnection öğesinin dahili olarak açılmasını ve kapatılmasını yönetir.

Benim soru çok parçalı olduğunu. Bu tasarım kötü mü? Öyleyse neden? o kötüyse

, bu gibi daha yerel kapsamda şeyler tutmak için değiştirilmesi gerektiğini şu:

public bool FillUsers(DataSet UserDataSet) 
    { 
     using (SqlConnection conn = new SqlConnection(ConnectionString)) 
     { 
      using (SqlCommand command = GetUsersSelectCommand()) 
      { 
       using (SqlDataAdapter adapter = new SqlDataAdapter(command, conn)) 
       { 
        adapter.Fill(UserDataSet, UsersTableName); 
       } 
      } 
     } 
    } 

Bu oluşturmak bertaraf gibi görünüyor tüm fonksiyonlar için yapılması gerekirdi ve Daha sonra yeniden yapılanma, öğeleri etrafta tutmaktan daha kötü olurdu. Ancak bu, her yerde çevrimiçi gördüğüm kurulum gibi görünüyor.

+0

Eğer optimize etmek ihtiyacı hissediyor böyle bir performans sorunu ölçmek mü? Veritabanı bağlantıları tasarım tarafından toplanır. Üstte "yeniden" yapmaya gerek yok. – spender

+0

Birkaç yıl önce sorduğum benzer bir soru: http://stackoverflow.com/questions/226127/multiple-single-instance-of-linq-to-sql-datacontext – spender

+0

Geriye dönük hiçbir performans sorunu yok. Yeni bir projeye başlıyorum ve bir veri erişim nesnesine ihtiyacım var ve bunun “doğru” ya da daha iyi bir yol olup olmadığını merak ettim. – Equixor

cevap

8

Hayır, bu yanlış bir şey yoktur. Onlarla bittiğinde, IDisposable'u uygulayan nesnelerinizi atmalısınız.

bir SqlConnection, bağlantı atarken, altta yatan bağlantı basitçe havuza iade edilecektir Verilen. Düşündüğünüz gibi mutlaka "kapalı" değil. Bağlantı havuzunun iş yapmasına izin vermek en iyisidir. Here, MSDN'de ADO.NET bağlantı havuzu için bir bağlantıdır. Bunu yapmak için tasarlanmayan şeyler yapmaya çalışmak (bazı insanlar bu optimizasyon olarak adlandırırlar, şaşırtıcı bir şekilde) genellikle tavşan deliğinden bir yolculuktur. Ayrıca

, aslında ölçülen ve optimize denemeden önce bir sorun gözlemledim emin olun. (Ve zamandan tasarruf yalnızca, sert bir şekilde bu demek değil).

+0

Üst kod, UserDatabase nesnesi atılıncaya kadar hiçbir nesneyi yok etmez. Öyleyse onları yeniden kullanmak, bu tasarım pratiğine karşı çıkacak mı? – Equixor

+0

@Equixor: Daha spesifik olarak SqlConnection'a atıfta bulunuyordum. Bu sınıf adı UserDatabase biraz yanıltıcıdır, çünkü gerçek bir veritabanı değildir. Belki de, kullanıcıların listesini döndüren GetUsers() adında bir yöntem oluşturabilirsiniz. İkinci kod yazınız doğru olan. Etrafında tutmak kötüdür (ve bazen hataların çoğaltılması zorlaşır) –

+0

Ok teşekkürler. Bunun genel tasarımının da geliştirilebileceğine eminim. Sahip olduğumuz DAL sınıflarının çoğu böyle ve BLL tarafından kullanılan veri kümelerini doldurmaktadır. – Equixor

İlgili konular