2009-12-30 2 views
0

я решил начать другую нить на основе ответов, которые я получил в этой теме: Asp.Net: Returning a Reader from a ClassAsp.Net: Возвращение DataSet из класса

Я возвращающая читателя, но члены предложили я бы лучше возвращать набор данных вместо этого, а также попытаться отделить уровень доступа к данным от уровня представления.

Это то, что я до сих пор: // мои методы класса

public DataSet GetSuppliers() 
    { 
     SqlConnection conn = new SqlConnection(connectionString); 
     SqlCommand cmd = new SqlCommand("con_spSuppliersList", conn); 
     cmd.CommandType = CommandType.StoredProcedure; 
     cmd.Parameters.AddWithValue("@blogid", HttpContext.Current.Request.QueryString["p"]); 

     return FillDataSet(cmd, "SuppliersList"); 
    } 

    //my FillDataSet method 

    private DataSet FillDataSet(SqlCommand cmd, string tableName) 
    { 
    SqlConnection conn = new SqlConnection(connectionString); 

    cmd.Connection = conn; 
    SqlDataAdapter adapter = new SqlDataAdapter(cmd); 

    DataSet ds = new DataSet(); 
     try 
     { 
      conn.Open(); 
      adapter.Fill(ds, tableName); 
     } 
     finally 
     { 
      conn.Close(); 
     } 
    return ds; 

    } 

// на моей странице ASCX я называю метод, как так:

protected void Page_Load(object sender, EventArgs e) 
{ 

    //instantiate our class 
    MyClass DB = new MyClass(); 

    // grab the table of data 
    DataTable dt = DB.GetSuppliers().Tables["SuppliersList"]; 

    //loop through the results 
    foreach (DataRow row in dt.Rows) 
    { 
     this.supplierslist.InnerHtml += Server.HtmlEncode(row["Address"].ToString()) + "<br/>"; 
     this.supplierslist.InnerHtml += "<b>Tel: </b>" + Server.HtmlEncode(row["Telephone"].ToString()) + "<p/>"; 

    } 


} 

}

Кто-нибудь хотел бы предложить улучшения?

Является ли мой цикл «уровня данных» или «уровнем представления», должен ли цикл быть внутри класса, и я просто возвращаю форматированную строку, установленную в наборе данных?

Спасибо за все большие советы

ответ

0

Одна вещь, вы должны войти в привычку делать зовёт Dispose() на вашем SqlConnection. Лучший способ сделать это - use the using statement, который автоматически удалит его для вас. Это выглядит следующим образом:

private DataSet FillDataSet(SqlCommand cmd, string tableName) 
{ 
    using(SqlConnection conn = new SqlConnection(connectionString)) 
    { 
     cmd.Connection = conn; 
     SqlDataAdapter adapter = new SqlDataAdapter(cmd); 

     DataSet ds = new DataSet(); 
     try 
     { 
      conn.Open(); 
      adapter.Fill(ds, tableName); 
     } 
     finally 
     { 
      conn.Close(); 
     } 
     return ds; 
    } 
} 
+0

Привет WOMP, если я использую 'с помощью' заявления, мне еще нужно conn.Close(); в моем методе FillDataSet? – Melt

+0

Нет, метод Dispose SqlConnection позаботится об этом для вас. Для других объектов, о которых вы не знаете наверняка, никогда не боится быть явным и оставить его. – womp

0

Что вы имеете в цикле Еогеаспа в Page_Load, это логика представления (макет), и ИМО, это не должно быть в коде-позади вашей страницы, но в разметке.

Я бы предположил, что вместо использования цикла foreach для построения вывода HTML вы должны использовать элемент управления с привязкой к базе данных (например, asp: Repeater, DataList или GridView). Затем вы можете привязать ретранслятор к вашему набору данных или datatable и иметь всю разметку, где он принадлежит (в файле ASCX). См. Пример this page.

Как общее примечание: вы можете найти множество руководств на www.asp.net, например. о доступе к данным: http://www.asp.net/%28S%28pdfrohu0ajmwt445fanvj2r3%29%29/learn/data-access/

1

Я также хотел бы использовать типизированный DataSet или создать свой собственный класс, содержащее свойство, так что вы не имеете дело со строками как row["Address"] вы сказали бы object.Address и получить компиляции проверки времени.

У наборов данных есть много встроенных функций, которые хороши, но также и кариес с ним много накладных расходов, которые могут быть не нужны в чем-то простом. Создание простого класса со свойствами и передача этого уровня доступа к данным - это, пожалуй, самый простой способ реализовать то, что вы хотите.

Нечто подобное на DAL (Access Data Layer) сторона:

//Also pass in the blogID dont have the DAL get the value from the UI layer.. 
    //make the UI layer pass it in. 
    public IList<Supplier> GetSuppliers(string connectionString, int blogID) 
    { 
     IList<Supplier> suppliers = new List<Supplier>(); 
     //wrap with the using statements 
     using (SqlConnection conn = new SqlConnection(connectionString)) 
     { 
      using (SqlCommand cmd = new SqlCommand("con_spSuppliersList", conn)) 
      { 
       cmd.CommandType = CommandType.StoredProcedure; 
       cmd.Parameters.AddWithValue("@blogid", blogID); 
       SqlDataReader reader = cmd.ExecuteReader(); 
       while (reader.Read()) 
       { 
        suppliers.Add(new Supplier 
        { 
         Address = reader.GetString(0), 
         Telephone = reader.GetString(1) 
        }); 
       } 
      } 
     } 

     return suppliers; 
    } 
} 

public class Supplier 
{ 
    //I would have Address an object....but you have as string 
    //public Address Address { get; set; } 
    public string Address { get; set; } 
    public string Telephone { get; set; } 
} 

//Example if you went with Address class... 
    public class Address 
    { 
     //Whatever you want in the address 
     public string StreetName { get; set; } 
     public string Country { get; set; } 
     public string Region { get; set; } 
     public string City { get; set; } 

} 
+0

Спасибо, я посмотрю. - Melt – Melt

+0

Я прихожу с некоторым примером кода ... – CSharpAtl

+0

Привет, CSharpAtl, Большое спасибо за код, я скопирую это и посмотрю, смогу ли я заставить его работать. – Melt

Смежные вопросы