1

我是 ASP.NET 的新手,

我正在制作国家,州下拉列表。

例如:对于特定国家,我将从缓存文件中读取该国家的状态。

逻辑:当用户第一次访问时,缓存将为空,因此将从缓存中获取相应XMLFile的状态并将其状态插入缓存,下次当用户访问同一国家/地区时,应从缓存中获取其状态,而不是从XMLFile.

我无法在我的下拉列表中获取所需国家/地区的状态...

这是我的代码片段,

protected void DropDownListCountry_SelectedIndexChanged(object sender, EventArgs e)
    {
           string  SelectedCountry = DropDownListCountry.SelectedItem.Text;

           XDocument doc = XDocument.Load(Server.MapPath("XMLFile.xml"));

           var query = from country in doc.Descendants("country")
                       where country.Attribute("name").Value == SelectedCountry
                       select new
                       {
                           states = from state in country.Elements("state")
                                    select new{
                                        Name = state.Attribute("name").Value
                                    }
                       };

           DataTable dt = new DataTable();
           dt.Columns.Add(new DataColumn("Name"));

            if (Cache["key"]==null)
            {
                foreach (var st in query)
                {
                    foreach (var StateName in st.states)
                    {
                        DataRow dr = dt.NewRow();
                        dr["Name"] = StateName.Name;
                        dt.Rows.Add(dr);
                        Cache.Insert("key", dr);

                    }
                }
                DropDownListState.DataSource = dt;
                DropDownListState.DataTextField = "Name";
                DropDownListState.DataBind();


            }
            else
            {
                      object obj = Cache["key"];
                      dt.Rows.Add(obj);

                DropDownListState.DataSource = dt;
                DropDownListState.DataTextField = "Name";
                DropDownListState.DataBind();
            }        
    }

提前致谢 !!

4

2 回答 2

2

这段代码几乎没有问题,比如处理数据和 UI 的方式,使用缓存,加上一个错误,每个对象的缓存键应该是唯一的。

因此,让我们重构一下代码并创建一个方法,该方法返回一个 DataTable,其中包含按国家/地区名称显示的州。如果状态已经在缓存中,则将返回缓存中的 DataTable。

private static DataTable GetStates(string countryName)
{
   DataTable dt = HttpContext.Current.Cache[countryName] as DataTable;
   if (dt != null)
       return dt;

   // the datatable is not in cache, let's create it then and add it to cache, next call will pick it from cache and won't read and parse the xml again
   var doc = XDocument.Load(HttpContext.Current.Server.MapPath("XMLFile.xml"));
   var query = from country in doc.Descendants("country")
                 where country.Attribute("name").Value == countryName
                 select new
                 {
                     states = from state in country.Elements("state")
                              select new
                              {
                                  Name = state.Attribute("name").Value
                              }
                 };

  dt = new DataTable();
  dt.Columns.Add(new DataColumn("Name"));

 foreach (var st in query)
            {
                foreach (var StateName in st.states)
                {
                    DataRow dr = dt.NewRow();
                    dr["Name"] = StateName.Name;
                    dt.Rows.Add(dr);

                }
            }
 // add the data table in the cache (not a row and don't use the same key)
 HttpContext.Current.Cache.Insert(countryName, dt);   
 // return this table
 return dt;
}

现在是事件处理程序

protected void DropDownListCountry_SelectedIndexChanged(object sender, EventArgs e)
    {
       var countryName = DropDownListCountry.SelectedItem.Text;
       var dt = GetStates(countryName);

       DropDownListState.DataSource = dt;
       DropDownListState.DataTextField = "Name"; // you can set it in markup also
       DropDownListState.DataBind();
    }

缓存由所有用户共享,所以如果这是您的意图,那么可以使用它。

于 2012-04-20T11:26:17.563 回答
0

这样的事情可能会有所帮助:

private DataTable PopulateCountryList()
{
  DataTable dt = (DataTable)Cache["countries"];

  if (dt == null)
  {
    dt.Columns.Add(new DataColumn("Name"));

    XDocument doc = XDocument.Load(Server.MapPath("XMLFile.xml"));

    var query = from country in doc.Descendants("country")
    where country.Attribute("name").Value == SelectedCountry
    select new
    {
        states = from state in country.Elements("state")
        select new {
        Name = state.Attribute("name").Value
        }
    };

    foreach (var st in query)
    {
        foreach (var StateName in st.states)
        {
          DataRow dr = dt.NewRow();
          dr["Name"] = StateName.Name;
          dt.Rows.Add(dr);    
        }
    }

    Cache.Insert("countries", dt, null, DateTime.Today.AddDays(1), TimeSpan.Zero);
  }

  return = dt;
}

当您要填充他的下拉列表时:

DropDownListState.DataSource = PopulateCountryList();
DropDownListState.DataTextField = "Name"; 
DropDownListState.DataBind();
于 2012-04-20T11:28:29.233 回答