EntityDataSource replace * with % wildcard on queries - asp.net

I have an application that uses EntityDataSource in many places.
In the EDS, I manually build the Where clause based on user input from TextBox'es.
I would like the user to be able to enter "*" (asterisks) instead of "%" when querying data.
Is there an easy as using Entity SQL or the EDS itself to do a search/replace? I know I could actually change the TextBox after the data is entered, but when the user sees his text was changed from an * to a % I don't think he will understand.
I have tried using the T-SQL Replace command and doing something like this:
<asp:EntityDataSource ID="EDSParts" runat="server"
ConnectionString="name=TTEntities" DefaultContainerName="TTEntities"
EnableFlattening="False" EntitySetName="Parts"
OrderBy="it.ID DESC"
Where ="(CASE
WHEN (#PartNumber IS NOT NULL) THEN
it.[Number] LIKE REPLACE(#PartNumber, "*", "%")
ELSE
it.[ID] IS NOT NULL
END)">
<WhereParameters>
<asp:ControlParameter Name="PartNumber" Type="String"
ControlID="txtPartNumberQuery" PropertyName="Text" />
</WhereParameters>
</asp:EntityDataSource>
But I get a "Server tag is not well formed" message. I can't find an equivalent "replace" function in the Entity SQL reference....
Any ideas?

You can handle page postback and modify content of txtPartNumberQuery. EntityDataSource can work only with % (because it builds ESQL query) so you have to change * to % in your codebehind before you execute databinding.

Sluama - Your suggestion fixed it! Such an obvious answer. The " was terminating the Where clause string. I could have sworn I tried that, but I guess not. Becuase, I just happened to come back to this question and saw your answer and it works!
<asp:EntityDataSource ID="EDSParts" runat="server"
ConnectionString="name=TTEntities" DefaultContainerName="TTEntities"
EnableFlattening="False" EntitySetName="Parts"
OrderBy="it.ID DESC"
Where ="(CASE
WHEN (#PartNumber IS NOT NULL) THEN
it.[Number] LIKE REPLACE(#PartNumber, '*', '%')
ELSE
it.[ID] IS NOT NULL
END)">
<WhereParameters>
<asp:ControlParameter Name="PartNumber" Type="String"
ControlID="txtPartNumberQuery" PropertyName="Text" />
</WhereParameters>
</asp:EntityDataSource>

Related

Asp:EntityDataSource: Make a insentitive diacritics search in where clause

I can't figure out how to do this.
I have a Gridview bind on a asp:EntityDataSource. This asp:EntityDataSource returns me a list of employe and the EntityDataSource can be filtered by a textbox on the name of the employee. I'm looking for a way to search by name being diacritics insentitive.
(Ex: Searching for "theroux" could return me "théroux" and/or "theroux". Or searching for "théroux" could return me "theroux" and/or "théroux")
I try searching in the canonical function but i didn't find anythings. Is there a way to do this without any code behind?
Here is my EntityDataSource
<asp:EntityDataSource ID="edsEmployes" runat="server"
ConnectionString="name=MyEntities" DefaultContainerName="MyEntities"
EntitySetName="Employes"
where="it.Name like '%'+#keyword+'%' ">
<WhereParameters>
<asp:ControlParameter ControlID="txtKeyword" DbType="String"
DefaultValue="%" Name="keyword" PropertyName="text" />
</WhereParameters>
</asp:EntityDataSource>
Assuming you're using SQL Server for you database I would try changing the collation on that field in the database to SQL_Latin1_General_CP1_CI_AI. The AI at the end means accent insensitive which should filter as you are wanting it to.

Dropdownlist filter inside details view

I have a drop down list (very long, over 100 items) inside the insert item template view for a details view. I would like to add a text box and button (search feature) so i can filter this list but i get the following error.
Databinding methods such as Eval(), XPath(), and Bind() can only be
used in the context of a databound control.
I created two entity datasource, one with a where clause and the other one without. When I hit search, the code behind (button click event) switches the datasource to the one with the where clause and parameter but i get the error above. Any advice on how to go about doing this?
Dim aa As DropDownList = DetailsView1.FindControl("DropDownList1")
aa.DataSourceID = ""
aa.DataSource = EmpPersonalInfoLOV1
aa.DataBind()
EDITED
Change aa.DataSource from a string to EmpPersonalInfoLOV1 (the name of the datasource)
EDIT #2
More info requested by users..
Datasource # 1 Code
<asp:EntityDataSource ID="EmpPersonalInfoLOV" runat="server"
ConnectionString="name=sspEntities" DefaultContainerName="sspEntities"
EnableFlattening="False" EntitySetName="Employee_Personal_Info"
EntityTypeFilter=""
Select="it.[Emp_id], it.[Employee_No_FastPay], it.[Surname] + ' '+ it.[Firstname] As FullName"
Where="">
</asp:EntityDataSource>
Datasource # 2 Code
<asp:EntityDataSource ID="EmpPersonalInfoLOV1" runat="server"
ConnectionString="name=sspEntities" DefaultContainerName="sspEntities"
EnableFlattening="False" EntitySetName="Employee_Personal_Info"
Select="it.[Emp_id], it.[Employee_No_FastPay], it.[Surname] + ' '+ it.[Firstname] As FullName"
Where="it.Surname like '%' + #Name + '%'">
<WhereParameters>
<asp:ControlParameter ControlID="TxtBx1" DbType="String"
DefaultValue="""" Name="Name" PropertyName="SelectedValue" />
</WhereParameters>
</asp:EntityDataSource>
It looks like you are not using the correct PropertyName on your EntityDataSource. Since you are getting the value from a textbox, the property you are getting is Text. Try this:
<asp:EntityDataSource ID="EmpPersonalInfoLOV1" runat="server"
ConnectionString="name=sspEntities" DefaultContainerName="sspEntities"
EnableFlattening="False" EntitySetName="Employee_Personal_Info"
Select="it.[Emp_id], it.[Employee_No_FastPay], it.[Surname] + ' '+ it.[Firstname] As FullName"
Where="it.Surname like '%' + #Name + '%'">
<WhereParameters>
<asp:ControlParameter ControlID="TxtBx1" DbType="String" Type="String" DefaultValue="" Name="Name" PropertyName="Text" />
</WhereParameters>
</asp:EntityDataSource>
Also, when you are using the like in your where clause, you really don't need two data objects. When the textbox is empty the query will select all.

ASP.NET SqlDataSource, like on SelectCommand

I'm working on asp.net. I Have a SqlDataSource with a query hardcoded on selectcommand:
<asp:SqlDataSource ID="DataSource1" runat="server" CancelSelectOnNullParameter="False"
ConnectionString="<%$ ConnectionStrings:S.Properties.Settings.ConnectionString %>"
SelectCommand="SELECT * FROM [table]
WHERE ([col1] like Case #col1_param When null Then col1 Else #col1_param End)
and ([col2] like Case #col2_param When null Then col2 Else #col2_param End)"
SelectCommandType="Text">
<SelectParameters>
<asp:ControlParameter ControlID="TextBox1" Name="col1_param" PropertyName="Text"
Type="String" />
<asp:ControlParameter ControlID="TextBox2" Name="col2_param" PropertyName="Text"
Type="String" />
</SelectParameters>
What I want is that if you enter data on one textbox only, the data will display according with that textbox value only on the where clause. And if no values are placed for neither of the textboxes, the the query executes as if there is no where.
Right now with this code,what happens is if you put on one textbox only no data is displayed. The same if all textboxes are empty.
I don't want to use sql stored procedure.
How can I solve this?
Thanks...
Assuming it passes null when there is no text entered, otherwise you will need to check for the empty string
SelectCommand="SELECT * FROM [table]
WHERE ([col1] like '%#col1_param%' or #col1_param is null)
and ([col2] like '%#col2_param%' or #col2_param is null)"
It sounds like you want your query to optionally search a column.
You can use the format
WHERE #col1_param IS NULL OR [col1] LIKE '%#col1_param%'
to property handle the case where the parameter is not specified.
See my question on the issue for a full answer. Granted it was done as a stored procedure, but the concept will hold the same for your SQLDataSource.

asp.ControlParamter control id conflict

<asp:ControlParameter ControlID="ddListPlayerPointSystems" Name="profileid" PropertyName="SelectedValue" />
<asp:ControlParameter ControlID="ddListCmty" Name="cmty" PropertyName="SelectedValue" />
<asp:ControlParameter ControlID="ctl00$MainContent$TabContainer1$TabPanel1$FormView3$pointsTextBox" Name="InsertPts" PropertyName="Text" Type="Decimal" />
I am having trouble understanding why in the first controlparameter i can call the dropdownbox id but not the textboxes id which is pointsTextBox. I am using a master page with an asp ajax tab container with multiple panels. If i take off the "ctl00$MainContent$TabContainer1$TabPanel1$FormView3$" i get a control not found but i dont know why this works for the other two controlparameters
EDIT
So I found a solution to my problem. Thanks to #TheGeekYouNeed and #JamesJ I understand why I would require the longer path name for that particular textbox (the drops were outside of the tabcontainer so the direct name worked). But I found that since I was assigning the value of that textbox via '<%# Bind("name", "{0:n}") %>' I was able to instead just use an asp:Parameter rather than the ControlParameter like so:
"<asp:Parameter Name="name" Type="String" />"
Problem is that i don't quite understand how that all works.
The ControlID for the pointsTextBox is not 'ct100$MainContent$TabContainer..etc... on the server side.
Set the COntrolID in the code behind, so you can use FindControl("pointsTextBox") to get a reference to the textbox control.
You could do something like:
TextBox t = this.FindControl("pointsTextBox") as TextBox;
if(t != null)
{
ddListPlayerPOintSystems.Add(new { COntrolID = t, Name = "InsertPts", PropertyName="Text", Type="Decimal"});
}
I haven't tested it, so I am not claiming the code is perfect, but the method you need to follow is illustrated here.

LinqDataSource and DateTime Format

I'm trying to create a LinqDataSource to bind to a DropDownList in an ASP.NET form. I only want to show the elements according to a date (which is one of the fields in the database).
Basically, the elements I want to show are the ones that will happen in the futures (i.e. after DateTime.Now).
I was trying the following markup :
<asp:DropDownList runat="server" ID="DropDownList1"
AppendDataBoundItems="True" DataSourceID="LinqDataSource1"
DataTextField="TextField" DataValueField="ValueField">
</asp:DropDownList>
<asp:LinqDataSource ID="LinqDataSource1" runat="server"
ContextTypeName="DataContext1" TableName="Table"
Where="DateField >= #DateField">
<WhereParameters>
<asp:Parameter DefaultValue="DateTime.Now" Name="DateField"
Type="DateTime" />
</WhereParameters>
</asp:LinqDataSource>
I'm getting a format exception saying that "The string was not recognized as a valid DateTime" when I try to run it. However, the dates in my database seem to be fine, because a DateTime.Parse works perfectly on them. The DateField is of type datetime in SQL.
What am I missing here?
Thanks!
The DefaultValue was what was wrong with the code as was suggested by the others.
However, setting the DefaultValue to
"<%# DateTime.Now %>"
like Andomar suggested (which would make the markup look something like this :
<WhereParameters>
<asp:Parameter DefaultValue="<%# DateTime.Now %>" Name="DateField" Type="DateTime" />
</WhereParameters>
will not work either because DataBinding expressions are only supported on objects that have a DataBinding Event, and neither Parameter or ControlParameter have one.
For a String, it's fairly easy to create a TextBox or Label and put the <%# %> expression in the value of that new field (more details here), but it was a bit more complicated with a DateTime value, as comparing an SQL DateTime with a .NET DateTime caused an exception.
It can be done quite easily in the Page_Load event by using
DataContext DataContext1 = new DataContext();
var c = from a in DataContext1.Field
where a.DateField >= DateTime.Now
select a;
DropDownList.DataSource = c;
DropDownList.DataBind();
I suspect it is failing on the DefaultValue.
Try:
DefaultValue="<%# DateTime.Now %>"

Resources