【问题标题】:The Page Page_Load Event Vs The Repeater ItemCommandPage Page_Load 事件与Repeater ItemCommand
【发布时间】:2010-12-12 03:04:18
【问题描述】:

我在 Page_Load 中运行一些代码,然后将此代码的结果存储在一些局部变量中。

现在我使用这个局部变量将它们分配给我的转发器项目模板中的控件

问题是>>页面不显示项目模板但没有数据绑定到它..我认为转发器无法加载在 Page_Load 中分配给它的数据并且它被初始化 - 生命周期相关问题-

知道问题到底是什么吗?以及如何解决这个问题?

编辑

一些示例代码:

public partial class MyPage: System.Web.UI.Page
    {

        int UserId = 0;

        protected void Page_Load(object sender, EventArgs e)
        {

            SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyDbConn"].ConnectionString);

            SqlCommand comm = new SqlCommand("SELECT * From Users, conn);
            SqlDataReader reader;

            conn.Open();
            reader = comm.ExecuteReader();

//I'm not sure if I need those two lines:
            AllBrandsRptr.DataSource = reader;
            AllBrandsRptr.DataBind();

            while (reader.Read())
            {

                    UserId = (int)reader["UserId"];
            }
                conn.Close();

            }
        }


    protected void AllBrandsRptr_ItemCommand(object source, RepeaterCommandEventArgs e)
    {

        Label LabelTest = (Label)e.Item.FindControl("MyTestLabel");
        LabelTest.Text = UserId.ToString();

    }

编辑 2

我的 Sql SELECT 语句

string command1 = "SELECT Brands.BrandId, Brands.BrandName, Brands.BrandLogo, Brands.BrandWebsite, Brands.IsBrandVisible, Cuisines.CuisineType, VenueTypes.VenueTypeName FROM         Brands FULL OUTER JOIN BrandCuisines ON BrandCuisines.BrandId = Brands.BrandId FULL OUTER JOIN Cuisines ON Cuisines.CuisineId = BrandCuisines.CuisineId FULL OUTER JOIN BrandVenueTypes ON BrandVenueTypes.BrandId = Brands.BrandId FULL OUTER JOIN VenueTypes ON VenueTypes.VenueTypeId = BrandVenueTypes.VenueTypeId";

我的过滤代码

            conn.Open();
            reader = comm.ExecuteReader();
            AllBrandsRptr.DataSource = reader;
            AllBrandsRptr.DataBind();

            while (reader.Read())
            {

                  if (((int)reader["BrandId"]) == BrandId) //this line to pass collecting some info, if I already iterated through the same Id 
                  {
                    BrandId = (int)reader["BrandId"];
                    BrandName = (string)reader["BrandName"];
                    BrandLogo = (string)reader["BrandLogo"];
                    BrandWebsite = (string)reader["BrandWebsite"];
                    IsVisible = (bool)reader["IsBrandVisible"];
                  }

                if (reader["CuisineType"] != DBNull.Value)
                {
                    Cuisines += (string)reader["CuisineType"];
                }

                if (reader["VenueTypeName"] != DBNull.Value)
                {
                    VenueTypes += ", " + (string)reader["VenueTypeName"];
                }

                conn.Close();

我最初的问题

How to use in my application a SELECT statement that must return more than one record to show multiple values for a certain field (m:m relation)

【问题讨论】:

  • 你能展示一些你真正想要做什么的代码吗?很难说你到目前为止得到了什么。
  • @Phill- 我添加了一些代码..似乎我不需要所有这些,但我确实在 while 循环中对我的数据进行了一些过滤以获取更多信息,您可以查看我之前的问题@ 987654322@

标签: c# asp.net sql


【解决方案1】:

您根本不应该手动迭代 DataReader。它是一个只进的工具。只有中继器 您的 while 循环可以遍历结果。我相信您的直接问题是您的 while 循环在 Repeater 呈现之前耗尽了 DataReader。

当您调用DataBind() 时,您是在指示Repeater 为您指定为其DataSource 的集合中的每个项目呈现其模板。因此,任何过滤都需要在之前进行。理想情况下,您应该将该过滤逻辑作为where 子句添加到您的 SQL 语句中。

您能否更具体地说明您要解决的实际问题?否则很难给你准确的建议。


更新:

请记住,while(reader.Read()) 不像事件处理程序那样工作,或者在其他方面类似于它在语义上可能听起来的方式。换句话说,您不是在告诉程序在读取 DataReader 时做某事,而是告诉它立即开始读取数据(与 Repeater 无关)。

以下是我建议您尝试的方法:

string sql = "Your current SQL here";
string connectionString = "Your connection string here";

// The using block ensures that the connection will be closed and freed up,
//  even if an unhandled exception occurs inside the block.
using (SqlConnection conn = new SqlConnection(connectionString))
{
  SqlCommand cmd = new SqlCommand(sql, conn);

  SqlDataAdapter da = new SqlDataAdapter(cmd);

  DataTable dt = new DataTable();

  da.Fill(dt);

  AllBrandsRptr.DataSource = dt;
  AllBrandsRptr.DataBind();

  var cuisineTypes = from row in dt.AsEnumerable()
                     select row["CuisineType"];

  string cuisines = string.Join(", ", cuisineTypes.Distinct());

  var venueTypes = from row in dt.AsEnumerable()
                   select row["VenueTypeName"];

  string venues = string.Join(", ", venueTypes.Distinct());
}

通过使用 DataTable 而不是 DataReader,您可以根据需要多次迭代数据。 DataReader 的性能更高,如果您只需要一次仅向前读取数据即可,但 DataTable 功能更强大,并且在 DataReader 功能之外的这些情况下也很有帮助。


值得一提的是,如果您长期关心这个项目并希望使其可维护,您应该考虑最终将部分数据访问代码移至单独的层。您应该努力在 .aspx.cs 文件中永远不要有 SQL 语句或直接数据访问代码。

然后,您在 Page_Load 中的代码可以是强类型的并且更易于使用:

List<Brand> brands = Brand.GetAllBrands();

AllBrandsRptr.DataSource = brands;
AllBrandsRptr.DataBind();

var cuisineTypes = from brand in brands
                   select brand.CuisineType;

string cuisines = string.join(", ", cuisineTypes.Distinct());

var venueTypes = from brand in brands
                 select brand.VenueType;

string venues = string.join(", ", venueTypes.Distinct());

【讨论】:

  • @Dave Ward- 我知道这有点难以理解,但我会尽量说清楚。这是我的最后一个问题,它有权解决主要问题stackoverflow.com/questions/4419344/… 并检查答案中的新编辑以获取确切的过滤逻辑和我正在使用的 SELECT 语句
  • @Dave Ward-这是一些非常好的信息,谢谢,标记为答案,但我希望你能提供帮助如果我还有其他问题,因为你已经熟悉了我的问题,我会在另一条评论中添加关于更新答案的我的 cmets
  • @Dave Ward- 我一直远离 DataTables,因为我听说它们的性能很差,我将 Repeater 与 DataReader 一起使用,因为它们是可用的最快工具,但也许是我需要的时候了更强大的工具,但您不认为使用stackoverflow.com/questions/614542/… 解决根本问题会更好吗?我很感谢你的 Layer 建议,我真的很喜欢架构,但我正在努力学习如何以正常的方式实现我所需要的,然后我会提升我的技能。
  • @Dave Ward- 抱歉,老兄用所有这些 cmets 来打扰你!但我开始回复然后我尝试应用您的代码,但我对如何使用此代码感到困惑!我的 Page_Load 事件是合适的地方吗?我没有准确地得到你的代码输出!我的意思是我应该在完成 ADO 代码后绑定吗?我认为我们需要使用某种循环来遍历每一行以检查它是否是相同的 id,这样我们就可以只提取美食和场地信息!我会为 ItemTemplate 使用相同的方法还是需要进行一些编辑?...真的很抱歉!..非常感谢 =)
  • 只要你需要多次使用查询的结果,很难让DataReader自己工作。您无需担心速度差异。对于像这样简单的事情,性能差异应该不明显。当您将数据对象(DataTable 或 DataReader,任一个)分配给 Repeater 的 DataSource,然后调用 DataBind 时,Repeater 会自行处理循环。如果你把我的代码放在你的 Page_Load 中,它应该会渲染中继器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-07
  • 2017-08-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多