如何使用相同的ObjectDataSource使用多个控件,但使用不同的过滤器

时间:2012-04-06 19:44:34

标签: c# asp.net c#-4.0 webforms

我正在玩ASP.Net WebForms中的优化。

在我的情况下,我有2个下拉菜单和一个网格。

我希望下拉列表充当网格的过滤器,每个过滤器都包含网格一列中不同的数据列表(用作过滤器)

那很好..我得到了它的工作,但我不能再使用相同的数据源作为下拉列表的网格了,因为我正在对数据源应用filterexpression来过滤网格中的什么。

因为它与下拉列表的数据源相同,所以我在下拉列表中得到一个较小的不同列表。

现在我可以使用多个数据源,每个数据源使用相同的数据对象,但我在Sql Profiler中看到有2个数据调用,但我真的想使用相同的数据源,所以我可以进行单个数据调用。

是否可以为网格过滤单个ObjectDataSource,同时为另一个控件提供未过滤的数据?

3 个答案:

答案 0 :(得分:3)

如果您专注于不必进行多个SQL调用,一个选项是使用LINQ查询DataSet中的SelectMethod。在语法上可能有更优雅的方式(我无法想出一个),但这应该使用单个ObjectDataSource提供所需的功能。

如果您的ObjectDataSource声明如下:

<asp:ObjectDataSource ID="myObjectDataSource" runat="server" SelectMethod="myObjectDataSource_Select" OnFiltering="myObjectDataSource_Filtering">

在您的SelectMethod中,您可以执行以下操作:

public DataSet myObjectDataSource_Select()
{
   string sqlQuery = "SELECT col1, col2, col3 FROM foo";
   SqlDataAdapter da = new SqlDataAdapter(sqlQuery, myConnectionString);
   DataSet ds = new DataSet();
   using (da) {
        da.Fill(ds);
   }

   //Perform your secondary filtering here
   object [] unfilteredQuery= (from r in ds.Tables[0].AsEnumerable()
        select r.Field<string>(“col1”)).ToArray();
   myUnfilteredComboBox.Items.Clear();
   myUnfilteredComboBox.Items.AddRange(unfilteredQuery);

   return ds;    
}

答案 1 :(得分:2)

你在使用Linq吗?如果是,那应该是可能的:

// Loading complete data into object
var myCompleteDataSource = (from c in ctx select c).ToList();

// Filtering the already loaded data
var myFilteredDataSource = myCompleteDataSource.Where(o=>o.MyField=="abc").ToList(); 

然后只需将数据源设置为您的对象。

这将仅从数据库加载您的数据一次(第一个.ToList()方法)并仅将对象列表过滤到第二个对象而不再访问数据库。

答案 2 :(得分:1)

  

正如你所说“因为它与下拉列表的数据源相同,所以我得到了一个   下拉列表中较小的不同列表。“

您可以将Database Information保留在 ViewState 中。通过这种方式,您可以阻止Request to Database用于您的客户端请求。因此Reducing the Access time

实施例

public DataTable Employees
{
    get
    {
        if (ViewState["Employees"] == null)
        {
            return FollowsDAL.GetAllEmployees();
        }
        return (DataTable)ViewState["Employees"];
    }
    set
    {
        ViewState["Employees"] = value;
    }
}

如何快速进行ViewState数据过滤?

答案是 - 请不要使用Update Panel。我将使用Page Method

请查看以下示例。我将Update PanelScript Manager一起使用。 enter image description here


输出

enter image description here

要显示22个字符的字符串,您可以检查接收和发送到服务器的数据量。想象一下

  1. 如果您考虑使用更新面板将每个请求发送到数据库,并且您的GridView位于Update Panel !!!!!!
  2. 如果您对每个请求使用 ViewState 数据,并在GridView内使用Update Panel
  3. 根据我的理解,上述技术都是最糟糕的。


    现在我将向您介绍页面方法

    更新页面方法面板

    Page methods允许ASP.NET AJAX页面使用Page’s Static Methods直接执行JSON (JavaScript Object Notation)。我们可以使用posting back and then receiving HTML markup来仅请求我们感兴趣的信息,而不是completely replace our UpdatePanel’s contentsweb method

    示例代码

    enter image description here enter image description here


    输出

    enter image description here


    所以结论是我肯定会将ViewState Page Methods一起使用。

    关于ViewState数据的过滤技术。

    public static class GetFilteredData
    {
        public static DataTable FilterDataTable(this DataTable Dt, 
                                                             string FilterExpression)
        {
            using (DataView Dv = new DataView(Dt))
            {
                Dv.RowFilter = FilterExpression;
                return Dv.ToTable();
            }
        }
    }
    

    实施例

    DataTableObject.FilterDataTable("Search Expression")
    

    你好vpiTriumph ......我发现代码有点改进。以下是建议的方法。

    C Sharp中的示例代码

    private void DsataBaseInteraction()
    {
        using (SqlConnection con = new SqlConnection("Your Connection String"))
        {
            using (SqlCommand cmd = new SqlCommand())
            {
                cmd.Connection = con;
                cmd.CommandType = System.Data.CommandType.StoredProcedure;
                cmd.CommandText = "Your Stored Procedure name";
                using (SqlDataReader DR = cmd.ExecuteReader())
                {
    
                }
            }
        }
    }
    

    @KevinDeus - 我假设使用的DatabaseSQL Server。所以下面提到的是我对Stored ProcedureDatabase的建议。

    Create Proc ProcedureName
    @UserName Varchar(50),
    @Password Varchar(50),
    @Email Varchar(50)
    As
    SET NOCOUNT ON
    SET XACT_ABORT ON
    
    Begin Try
        Begin Tran
            Insert into Account (Username,Password, Email)
            Values(@UserName, @Password, @Email)
        Commit Tran 
    End Try
    
    Begin Catch
        Rollback Tran
    End Catch
    

    参考是 Here Here