DotNetNukeŽ User Search: Advanced Searching using Linq

This program allows users to add unlimited rows of search criteria to filter a list. This example uses the DotNetNuke Users table (normally you would not want to connect directly to a DotNetNuke core table. It is only used as an example).

The Code

using System;
using DotNetNuke.Entities.Modules;
using System.Linq;
using DotNetNuke.Services.Exceptions;
using System.Web.UI.WebControls;
using System.Web.UI;
using System.Collections.Generic;

namespace DotNetNuke.Modules.UserSearch
{
    #region SearchCriteria
    [Serializable]
    public class SearchCriteria
    {
        public string Field { get; set; }
        public string CriteriaType { get; set; }
        public string Criteria { get; set; }
    }
    #endregion

    public partial class View : PortalModuleBase
    {
        #region Viewstate

        #region CurrentRow
        public int CurrentRow
        {
            get
            {
                if (ViewState["CurrentRow"] == null)
                {
                    return 0;
                }
                else
                {
                    return (int)ViewState["CurrentRow"];
                }
            }
            set
            {
                ViewState["CurrentRow"] = value;
            }
        }
        #endregion

        #region Criteria
        public List<SearchCriteria> Criteria
        {
            get
            {
                if (ViewState["Criteria"] == null)
                {
                    return new List<SearchCriteria>();
                }
                else
                {
                    return (List<SearchCriteria>)ViewState["Criteria"];
                }
            }
            set
            {
                ViewState["Criteria"] = value;
            }
        }
        #endregion

        #endregion

        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                if (!Page.IsPostBack)
                {
                    // Load one row of search criteria
                    AddCriteriaRow();
                }
            }
            catch (Exception exc)
            {
                // Module failed to load
                Exceptions.ProcessModuleLoadException(this, exc);
            }
        }

        #region AddCriteriaRow
        private void AddCriteriaRow()
        {
            // Add the Table to DCP panel
            Table objTable = new Table();
            DCP.Controls.Add(objTable);
            objTable.ID = String.Format("CriteriaTable_{0}", CurrentRow.ToString());

            // Create Controls
            TableRow TableRow = new TableRow();
            TableCell TableCell = new TableCell();
            Button btnDelete = new Button();
            DropDownList dlField = new DropDownList();
            DropDownList dlCriteriaType = new DropDownList();
            TextBox txtCriteria = new TextBox();
            Button btnAddNew = new Button();

            // Setup Table
            TableRow.Cells.Add(TableCell);
            objTable.Rows.Add(TableRow);

            // Add Controls to the Table
            TableCell.Controls.Add(btnDelete);
            TableCell.Controls.Add(dlField);
            TableCell.Controls.Add(dlCriteriaType);
            TableCell.Controls.Add(txtCriteria);
            TableCell.Controls.Add(btnAddNew);
            TableCell.Style.Add(HtmlTextWriterStyle.TextAlign, "left");
            TableCell.Style.Add(HtmlTextWriterStyle.Padding, "5");
            TableCell.Wrap = false;

            // Add properties to the Controls
            btnDelete.Text = "Delete";
            dlField.Items.Add(new ListItem("Username"));
            dlField.Items.Add(new ListItem("First Name"));
            dlField.Items.Add(new ListItem("Last Name"));
            dlField.Items.Add(new ListItem("Email"));
            dlCriteriaType.Items.Add(new ListItem("Contains"));
            dlCriteriaType.Items.Add(new ListItem("Not Contain"));
            dlCriteriaType.Items.Add(new ListItem("Starts With"));
            dlCriteriaType.Items.Add(new ListItem("Ends With"));
            btnAddNew.Text = "Add New Row";

            // Create ID's for controls so they will be persisted in ViewState
            TableRow.ID = String.Format("{0}_TableRow", CurrentRow.ToString());
            TableCell.ID = String.Format("{0}_TableCell", CurrentRow.ToString());
            btnDelete.ID = String.Format("{0}_btnDelete", CurrentRow.ToString());
            dlField.ID = String.Format("{0}_dlField", CurrentRow.ToString());
            dlCriteriaType.ID = String.Format("{0}_dlCriteriaType", CurrentRow.ToString());
            txtCriteria.ID = String.Format("{0}_txtCriteria", CurrentRow.ToString());
            btnAddNew.ID = String.Format("{0}_btnAddNew", CurrentRow.ToString());

            // Disable the Delete button oo the first row
            btnDelete.Enabled = (CurrentRow > 0);

            CurrentRow++;
        }
        #endregion

        // Button events

        #region btnDelete_Click
        void btnDelete_Click(object sender, EventArgs e)
        {
            Button btnDelte = (Button)sender;

            // Determine what row the button is in
            int intRowToDelete = Convert.ToInt32(btnDelte.ID.Replace("_btnDelete", ""));

            // Find the row
            Control ctlRowToDelete = (from CriteriaTable in DCP.Controls.Cast<Control>().AsQueryable()
                                      where CriteriaTable.ID ==
                                      String.Format("CriteriaTable_{0}", intRowToDelete.ToString())
                                      select CriteriaTable).FirstOrDefault();

            // Remove the row
            DCP.Controls.Remove(ctlRowToDelete);
        }
        #endregion

        #region btnAddNew_Click
        void btnAddNew_Click(object sender, EventArgs e)
        {
            // Add a row of search criteria
            AddCriteriaRow();
        }
        #endregion

        #region btnSubmit_Click
        protected void btnSubmit_Click(object sender, EventArgs e)
        {
            // Gather search values
            List<SearchCriteria> colSearchCriteria = new List<SearchCriteria>();

            // Get the Tables
            var colTables = from CriteriaTable in DCP.Controls.Cast<Control>().AsQueryable()
                            select CriteriaTable;

            foreach (var objTable in colTables)
            {
                SearchCriteria objSearchCriteria = new SearchCriteria();

                // Get the current row Number
                int intRowNumber = Convert.ToInt32(objTable.ID.Replace("CriteriaTable_", ""));

                // Get Field dropdown
                DropDownList dlField = (DropDownList)objTable.
                    FindControl(String.Format("{0}_dlField", intRowNumber.ToString()));

                // Get CriteriaType dropdown
                DropDownList dlCriteriaType = (DropDownList)objTable.
                    FindControl(String.Format("{0}_dlCriteriaType", intRowNumber.ToString()));

                // Get Criteria TextBox
                TextBox txtCriteria = (TextBox)objTable.
                    FindControl(String.Format("{0}_txtCriteria", intRowNumber.ToString()));

                objSearchCriteria.Field = dlField.SelectedValue;
                objSearchCriteria.CriteriaType = dlCriteriaType.SelectedValue;
                objSearchCriteria.Criteria = txtCriteria.Text;

                colSearchCriteria.Add(objSearchCriteria);
            }

            // Store criteria in Viewstate
            Criteria = colSearchCriteria;
            // Refresh user list
            lvUsers.DataBind();
        }
        #endregion

        // Attach Click events to the buttons

        #region DCP_ControlRestored
        protected void DCP_ControlRestored(object sender, DynamicControlEventArgs e)
        {
            if (e.DynamicControl.ID.Contains("_btnDelete"))
            {
                Button btnDelete = (Button)e.DynamicControl;
                btnDelete.Click += new EventHandler(btnDelete_Click);
            }

            if (e.DynamicControl.ID.Contains("_btnAddNew"))
            {
                Button btnAddNew = (Button)e.DynamicControl;
                btnAddNew.Click += new EventHandler(btnAddNew_Click);
            }
        }
        #endregion

        // Display ussers

        #region LDSUsers_Selecting
        protected void LDSUsers_Selecting(object sender, System.Web.UI.WebControls.LinqDataSourceSelectEventArgs e)
        {
            if (Criteria != null)
            {
                List<SearchCriteria> colSearchCriteria = (List<SearchCriteria>)Criteria;

                UserSearchDALDataContext db = new UserSearchDALDataContext();

                var colUsers = from Users in db.Users
                               select Users;

                // Filter Results

                #region Contains
                foreach (var CriteriaItem in colSearchCriteria.
                            Where(x => x.Field == "Username").
                            Where(y => y.CriteriaType == "Contains"))
                {
                    colUsers = from Users in colUsers
                               where Users.Username.
                               Contains(CriteriaItem.Criteria)
                               select Users;
                }

                foreach (var CriteriaItem in colSearchCriteria.
                    Where(x => x.Field == "First Name").
                    Where(y => y.CriteriaType == "Contains"))
                {
                    colUsers = from Users in colUsers
                               where Users.FirstName.
                               Contains(CriteriaItem.Criteria)
                               select Users;
                }

                foreach (var CriteriaItem in colSearchCriteria.
                    Where(x => x.Field == "Last Name").
                    Where(y => y.CriteriaType == "Contains"))
                {
                    colUsers = from Users in colUsers
                               where Users.LastName.
                               Contains(CriteriaItem.Criteria)
                               select Users;
                }

                foreach (var CriteriaItem in colSearchCriteria.
                    Where(x => x.Field == "Email").
                    Where(y => y.CriteriaType == "Contains"))
                {
                    colUsers = from Users in colUsers
                               where Users.Email.
                               Contains(CriteriaItem.Criteria)
                               select Users;
                } 
                #endregion

                #region Not Contain
                foreach (var CriteriaItem in colSearchCriteria.
                           Where(x => x.Field == "Username").
                           Where(y => y.CriteriaType == "Not Contain"))
                {
                    colUsers = from Users in colUsers
                               where !Users.Username.
                               Contains(CriteriaItem.Criteria)
                               select Users;
                }

                foreach (var CriteriaItem in colSearchCriteria.
                    Where(x => x.Field == "First Name").
                    Where(y => y.CriteriaType == "Not Contain"))
                {
                    colUsers = from Users in colUsers
                               where !Users.FirstName.
                               Contains(CriteriaItem.Criteria)
                               select Users;
                }

                foreach (var CriteriaItem in colSearchCriteria.
                    Where(x => x.Field == "Last Name").
                    Where(y => y.CriteriaType == "Not Contain"))
                {
                    colUsers = from Users in colUsers
                               where !Users.LastName.
                               Contains(CriteriaItem.Criteria)
                               select Users;
                }

                foreach (var CriteriaItem in colSearchCriteria.
                    Where(x => x.Field == "Email").
                    Where(y => y.CriteriaType == "Not Contain"))
                {
                    colUsers = from Users in colUsers
                               where !Users.Email.
                               Contains(CriteriaItem.Criteria)
                               select Users;
                } 
                #endregion

                #region Starts With
                foreach (var CriteriaItem in colSearchCriteria.
                            Where(x => x.Field == "Username").
                            Where(y => y.CriteriaType == "Starts With"))
                {
                    colUsers = from Users in colUsers
                               where Users.Username.
                               StartsWith(CriteriaItem.Criteria)
                               select Users;
                }

                foreach (var CriteriaItem in colSearchCriteria.
                    Where(x => x.Field == "First Name").
                    Where(y => y.CriteriaType == "Starts With"))
                {
                    colUsers = from Users in colUsers
                               where Users.FirstName.
                               StartsWith(CriteriaItem.Criteria)
                               select Users;
                }

                foreach (var CriteriaItem in colSearchCriteria.
                    Where(x => x.Field == "Last Name").
                    Where(y => y.CriteriaType == "Starts With"))
                {
                    colUsers = from Users in colUsers
                               where Users.LastName.
                               StartsWith(CriteriaItem.Criteria)
                               select Users;
                }

                foreach (var CriteriaItem in colSearchCriteria.
                    Where(x => x.Field == "Email").
                    Where(y => y.CriteriaType == "Starts With"))
                {
                    colUsers = from Users in colUsers
                               where Users.Email.
                               StartsWith(CriteriaItem.Criteria)
                               select Users;
                }
                #endregion

                #region Ends With
                foreach (var CriteriaItem in colSearchCriteria.
                            Where(x => x.Field == "Username").
                            Where(y => y.CriteriaType == "Ends With"))
                {
                    colUsers = from Users in colUsers
                               where Users.Username.
                               EndsWith(CriteriaItem.Criteria)
                               select Users;
                }

                foreach (var CriteriaItem in colSearchCriteria.
                    Where(x => x.Field == "First Name").
                    Where(y => y.CriteriaType == "Ends With"))
                {
                    colUsers = from Users in colUsers
                               where Users.FirstName.
                               EndsWith(CriteriaItem.Criteria)
                               select Users;
                }

                foreach (var CriteriaItem in colSearchCriteria.
                    Where(x => x.Field == "Last Name").
                    Where(y => y.CriteriaType == "Ends With"))
                {
                    colUsers = from Users in colUsers
                               where Users.LastName.
                               EndsWith(CriteriaItem.Criteria)
                               select Users;
                }

                foreach (var CriteriaItem in colSearchCriteria.
                    Where(x => x.Field == "Email").
                    Where(y => y.CriteriaType == "Ends With"))
                {
                    colUsers = from Users in colUsers
                               where Users.Email.
                               EndsWith(CriteriaItem.Criteria)
                               select Users;
                }
                #endregion

                e.Result = colUsers;
            }
        }
        #endregion

    }
}

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="View.ascx.cs" 
Inherits="DotNetNuke.Modules.UserSearch.View" %>
<%@ Register TagPrefix="dbwc" Namespace="DotNetNuke.Modules.UserSearch" %>
<asp:LinqDataSource ID="LDSUsers" runat="server" 
ContextTypeName="DotNetNuke.Modules.UserSearch.UserSearchDALDataContext"
    OrderBy="LastName" TableName="Users" OnSelecting="LDSUsers_Selecting">
</asp:LinqDataSource>
<asp:Panel ID="pnlCriteria" runat="server" GroupingText="Search Criteria">
    <dbwc:DynamicControlsPlaceholder ID="DCP" runat="server" 
        ControlsWithoutIDs="DontPersist" oncontrolrestored="DCP_ControlRestored">
    </dbwc:DynamicControlsPlaceholder>
    <br />
    <asp:Button ID="btnSubmit" runat="server" Text="Search" 
        OnClick="btnSubmit_Click" />
</asp:Panel>

<asp:ListView ID="lvUsers" runat="server" DataKeyNames="UserID" DataSourceID="LDSUsers">
    <ItemTemplate>
        <tr style="">
            <td>
                <asp:Label ID="UserIDLabel" runat="server" Text='<%# Eval("UserID") %>' />
            </td>
            <td>
                <asp:Label ID="UsernameLabel" runat="server" Text='<%# Eval("Username") %>' />
            </td>
            <td>
                <asp:Label ID="FirstNameLabel" runat="server" Text='<%# Eval("FirstName") %>' />
            </td>
            <td>
                <asp:Label ID="LastNameLabel" runat="server" Text='<%# Eval("LastName") %>' />
            </td>
            <td>
                <asp:Label ID="EmailLabel" runat="server" Text='<%# Eval("Email") %>' />
            </td>
        </tr>
    </ItemTemplate>
    <EmptyDataTemplate>
        <table runat="server" style="">
            <tr>
                <td>
                    No data was returned.
                </td>
            </tr>
        </table>
    </EmptyDataTemplate>
    <LayoutTemplate>
        <table runat="server">
            <tr runat="server">
                <td runat="server">
                    <table id="itemPlaceholderContainer" runat="server" border="0" style="">
                        <tr runat="server" style="">
                            <th runat="server">
                                User ID
                            </th>
                            <th runat="server">
                                Username
                            </th>
                            <th runat="server">
                                First Name
                            </th>
                            <th runat="server">
                                Last Name
                            </th>
                            <th runat="server">
                                Email
                            </th>
                        </tr>
                        <tr id="itemPlaceholder" runat="server">
                        </tr>
                        <tr id="Tr1" runat="server">
                            <td id="Td1" runat="server" colspan="5">
                                <asp:DataPager ID="DataPager1" runat="server">
                                    <Fields>
                                        <asp:NextPreviousPagerField ButtonType="Button" 
                                        ShowFirstPageButton="True" ShowNextPageButton="False"
                                            ShowPreviousPageButton="False" />
                                        <asp:NumericPagerField />
                                        <asp:NextPreviousPagerField ButtonType="Button" 
                                        ShowLastPageButton="True" ShowNextPageButton="False"
                                            ShowPreviousPageButton="False" />
                                    </Fields>
                                </asp:DataPager>
                            </td>
                        </tr>
                    </table>
                </td>
            </tr>
        </table>
    </LayoutTemplate>
</asp:ListView>

Advanced Searching using Linq to SQL

Even though there is a lot of Linq code to construct the queries, there is only one trip to the database to execute the query.  

Download the code: UserSearch_01.00.00_Install.zip (install and source)
Note: If using DNN4 install and run LinqPrep first.

[Back to: The ADefWebserver DotNetNuke HELP WebSite]


DotNetNukeŽ is a registered trademark of the DotNetNuke Corporation