Asp.Net Linq and XML query - asp.net

I'm trying to grab some data using LINQ and a "WHERE" function within my "SELECT" function
Here's my sample XML
<Items>
<Extras>
<Extra Code="TEST1" Quantity="1" />
<Extra Code="TEST2" Quantity="1" />
</Extras>
<Options>
<OptionalExtra Description="Test 1" Code="TEST1" type="TESTING1" />
<OptionalExtra Description="Test 2" Code="TEST2" type="TESTING2" />
</Options>
</Items>
And here's my LINQ query
bookingsInfo = xel.Descendants("Extras").Descendants("Extra") _
.Select(Function(f) New With { _
.Code = f.Attributes("Code").First.Value, _
.Type = f.Parent.Parent.Descendants("Options").Descendants("OptionalExtra") _
.Where(Function(g) g.Attributes("Code").First.Value = _
f.Attributes("Code").First.Value).Attributes("type").First.Value, _
.Quantity = f.Attributes("Quantity").First.Value _
})
The "TYPE" is the problem I'm having trouble getting and I'm not really sure what the issue is.
I don't have any control of how the XML is laid out but I can edit the LINQ query no problem.
Does anyone have any suggestions?
Thanks in advance

I think it will be easier to use Join instead of Parent.Parent:
Dim bookingsInfo = From e In xel.Root.<Extras>.<Extra>
Join o In xel.Root.<Options>.<OptionalExtra> On e.#Code Equals o.#Code
Select New With {
.Code = e.#Code,
.Type = o.#Type,
.Quantity = e.#Quantity
}

Related

Change SqlDataSource ConnectionStrings value in code behind (vb.net)

I currently have this code in the front of my ASP.NET page
<asp:SqlDataSource ID="SqlDataSourceRecentJobs" runat="server"
ConnectionString="<%$ ConnectionStrings:ConnectionString_DEV_customer_support %>"
ProviderName="<%$ ConnectionStrings:ConnectionString_DEV_customer_support.ProviderName %>"
SelectCommand="SELECT job_id FROM time_recorder_jobs WHERE (deleted = 0) ORDER BY job_id DESC LIMIT 1">
</asp:SqlDataSource>
Which works fine.
However, I want to set or define the value of 'ConnectionStrings' using the codebehind - based on a session variable.
My web.config contains:
<connectionStrings>
<add name="ConnectionString_DEV_customer_support" connectionString="server=REMOVED;port=REMOVED;User Id=REMOVED;password=REMOVED;Persist Security Info=True;database=dev_customer_support;Sql Server Mode=True;Allow User Variables=True" providerName="MySql.Data.MySqlClient" />
<add name="ConnectionString_LIVE_customer_support" connectionString="server=REMOVED;port=REMOVED;User Id=REMOVED;password=REMOVED;Persist Security Info=True;database=customer_support;Sql Server Mode=True;Allow User Variables=True" providerName="MySql.Data.MySqlClient" />
</connectionStrings>
So I wish to set either ConnectionString_DEV_customer_support or ConnectionString_LIVE_customer_support in the code behind, depending on which server environment the user is on.
I thought something like this would work (but it does not):
Dim SqlDataSourceRecentJobs As New SqlDataSource()
If Session("Environment") = "LIVE" Then
strUseThisDB = "ConnectionString_LIVE_customer_support"
Else
strUseThisDB = "ConnectionString_DEV_customer_support"
End If
SqlDataSourceRecentJobs.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings(strUseThisDB).ConnectionString
Using the code behind (I use VB, not C#), how do I set/define/specify which of my ConnectionStrings I want to use?
Just to add, if it makes a difference, I also want to set the SELECT in the code behind too.
Eg.
SqlDataSourceRecentJobs.SelectCommand = "SELECT time_recorder_jobs.job_id, time_recorder_jobs.user_id, time_recorder_jobs.operation_id, time_recorder_jobs.task_id, time_recorder_jobs.customer_id, time_recorder_jobs.farm_id, time_recorder_jobs.output, time_recorder_jobs.start_time, time_recorder_jobs.end_time, time_recorder_jobs.comments FROM time_recorder_jobs INNER JOIN time_recorder_users ON time_recorder_jobs.user_id = time_recorder_users.user_id INNER JOIN time_recorder_companies ON time_recorder_users.company_id = time_recorder_companies.company_id WHERE (time_recorder_jobs.deleted = #deleted) AND (time_recorder_users.company_id = #companyid) ORDER BY time_recorder_jobs.job_id DESC LIMIT 10"
SqlDataSourceRecentJobs.SelectParameters.Clear()
SqlDataSourceRecentJobs.SelectParameters.Add("#companyid", Session("CompanyID"))
SqlDataSourceRecentJobs.SelectParameters.Add("#deleted", 0)
You could do something like this:
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
SqlDataSourceRecentJobs = New SqlDataSource
conn = New MySqlConnection
If ConfigurationManager.ConnectionStrings("ConnectionString_DEV_customer_support").ConnectionString Is Nothing OrElse _
ConfigurationManager.ConnectionStrings("ConnectionString_DEV_customer_support").ConnectionString.Trim() = "" Then
Throw New Exception("Connection Error")
Else
conn.ConnectionString = ConfigurationManager.ConnectionStrings("ConnectionString_DEV_customer_support").ConnectionString
End If
SqlDataSourceRecentJobs.ConnectionString = conn.ConnectionString
SqlDataSourceRecentJobs.ID = "SqlDataSourceRecentJobs"
SqlDataSourceRecentJobs.ProviderName = "MySql.Data.MySqlClient"
SqlDataSourceRecentJobs.SelectCommand = "SELECT * FROM time_recoder_jobs"
SqlDataSourceRecentJobs.CancelSelectOnNullParameter = False
Me.Controls.Add(SqlDataSourceRecentJobs)
End Sub
I use the Page_Init to load the DataSource

VB.Net and XDocument - Group By

I have the following code which I need to amend to group by offer but I'm not sure how to add in the group by part in this query.
Any ideas?
propertyInfo = myXmlFile.Descendants("offer").Descendants("site") _
.Where(Function(f) _
f.Attributes("code").First.Value = Location.Text) _
.Select(Function(f) New With { _
.LOCATION = f.Attributes("code").First.Value, _
.TITLE = f.Parent.Attributes("title").First.Value, _
.OFFER = f.Parent.Attributes("offerid").First.Value, _
.POPUPDESC = f.Parent.Descendants("short_desc").Value
Example XML
<offers>
<offer title="Offer title" offerid="AS32">
<short_desc><![CDATA[
<div>Your HTML's body <a href='dfgdfgdfgdfg.html'>Offer title</a>
</div>
]]></short_desc>
<site code="CO">
<year_week_start>201344</year_week_start>
<year_week_end>201414</year_week_end>
</site>
<site code="FH">
<year_week_start>201446</year_week_start>
<year_week_end>201450</year_week_end>
</site>
</offer>
</offers>
I think you need to be a little more specific in what you want after you group. It's pretty easy to group, but then you get an enumerable of groups:
propertyInfo = myXmlFile.Descendants("offer").Descendants("site") _
.Where(Function(f) _
f.Attributes("code").First.Value = Location.Text) _
.Select(Function(f) New With { _
.LOCATION = f.Attributes("code").First.Value, _
.TITLE = f.Parent.Attributes("title").First.Value, _
.OFFER = f.Parent.Attributes("offerid").First.Value, _
.POPUPDESC = f.Parent.Descendants("short_desc").Value) _
.GroupBy(Function(f) f.OFFER)

I'm having trouble querying an XDocument using LINQ

I'm new to LINQ so I gather I just have some of my syntax wrong. I've looked at many examples online but everyone seems to have their own style.
Here's the XML data I'm querying against:
<ajax-response>
<response type="object" id="unknown">
<generic response="Success" message="Channel status will follow" />
</response>
<response type="object" id="unknown">
<generic event="Status" privilege="Call" channel="SIP/452-000006fc" calleridnum="452" calleridname="Joe" connectedlinenum="430" connectedlinename="device" accountcode="" channelstate="6" channelstatedesc="Up" context="macro-dial-one" extension="s" priority="37" seconds="54" bridgedchannel="SIP/430-000006fd" bridgeduniqueid="1363822334.1829" uniqueid="1363822334.1828" />
</response>
<response type="object" id="unknown">
<generic event="Status" privilege="Call" channel="SIP/430-000006fd" calleridnum="430" calleridname="device" connectedlinenum="452" connectedlinename="Joe" account="" state="Up" bridgedchannel="SIP/452-000006fc" bridgeduniqueid="1363822334.1828" uniqueid="1363822334.1829" />
</response>
<response type="object" id="unknown">
<generic event="StatusComplete" items="2" />
</response>
</ajax-response>
and here's what I have so far:
Function ParseXML(statusXML As XmlDocument) As String
Dim xdoc As XDocument = XDocument.Load(New XmlNodeReader(statusXML))
Dim parsed As StringBuilder = New StringBuilder()
Dim query = From generic In xdoc.Descendants("generic") _
Where generic.Attribute("privilege") IsNot Nothing And generic.Attribute("privilege").Value = "Call" _
Select connectedlinenum = generic.Attribute("connectedlinenum").ToString, _
calleridnum = generic.Attribute("calleridnum").ToString
For Each i In query
parsed.Append(i.connectedlinenum).Append(",").Append(i.calleridnum).Append(vbCrLf)
Next
Return parsed.ToString
End Function
I'm guessing I am misunderstanding how my generic object is supposed to be working, because I get a NullReferenceException in my Where clause when I try to reference it.
I'm not familiar with Xml parsing, but in two of the nodes you do not have the privilege attribute. Could that be causing the error?
In that case, what happens if you change the And to AndAlso in the Where clause? That way it would not evaluate the latter part of the statement if there is no privilege attribute.

Why doesn't asp.net make pagination efficiently on gridview controls?

I have a site with thousands of records and every time I make an action the gridview send around 300kb by ajax.
I try to make a custom pagination maintaining the ajax functionality, sorting, but it is so complicated.
I search for a hack to this but I don't find anything.
Links about:
http://www.nikhedonia.com/notebook/entry/efficient-paging-for-gridview/
http://kpumuk.info/asp-net/gridview-with-custom-digg-like-pager/
#mellamokb, this is the way I databind the gridview
CODE:
Dim res = From r In dc.Reservas _
From u In dc.UsuariosData Where r.usr_Id = u.usr_Id _
From c In dc.Campings Where c.camp_Id = r.camp_Id And r.sta_Id <> 2 _
From rec In dc.OrdenesRegistros Where rec.rec_Id = r.rec_Id _
From o In dc.Ordenes Where o.ord_Id = rec.ord_Id _
From p In dc.Pagos Where p.pay_Id = o.pay_Id _
From z In dc.Zonas Where z.zon_Id = r.zon_Id _
Select New With {.res_Id = r.res_Id, _
.usr_NickName = u.usr_NickName, .usr_Name = u.usr_Name, _
.usr_LastName = u.usr_LastName, .usr_Email = u.usr_Email, _
.usr_Cel = u.usr_Cel, .camp_Name = c.camp_Name, _
.res_CreationDate = r.res_CreationDate, _
.pay_Name = p.pay_Name, _
.sta_Id = r.sta_Id, .camp_Id = c.camp_Id, .res_StartDate = r.res_StartDate, _
.res_EndDate = r.res_EndDate, .zon_Id = z.zon_Id}
Session("datosGridView") = res
GridView_ZC.DataSource = Session("datosGridView")
GridView_ZC.DataBind()
The pagination should be handled by the data source control. If you are using a LinqDataSource control, then it should do the pagination with AutoPage="true" AFAIK.
Edit
Your data source has no pagination, so all of the data has to flow to the GridView before the GridView can paginate it. Your LINQ-to-SQL query returns all records.
You want to use a "smart" data source, like a LinqDataSource control. The easiest way is to declare a LinqDataSource, bind the GridView to the data source in the markup, and then override the Selecting event of the LinqDataSource to specify your custom data retrieval logic:
<asp:LinqDataSource ID="MyDataSource" runat="server"
OnSelecting="MyDataSource_Selecting" AutoPage="true" AutoSort="true">
</asp:LinqDataSource>
<asp:GridView ID="MyGridView" DataSourceID="MyDataSource" ... >
The code-behind:
Protected Sub MyDataSource_Selecting(sender As Object, _
e As LinqDataSourceSelectingEventArgs)
Dim dataContext As New MyDataContext
e.Result = ' Put LINQ-to-SQL code here
End Sub
Check this : http://www.seila.gov.kh/eang/ASPNET2.0/Web_2.0_With_ASP_NET_3.5.pdf
There a few chapters about optimization and perfomance, I recall reading something about gridview controls.

Auto Suggested Text Box with concatenated string with LINQ to SQL

I'm creating a text box with auto-suggested. So, it works well. It suggests only first name, but I want it to suggest the full name (first and last name which two different columns). Take a look at the following code behind that worked as expected :
<System.Web.Services.WebMethod()> _
Public Shared Function GetNames(ByVal prefixText As String, ByVal count As Integer) As String()
Dim db As New DemoDataContext()
Return db.Students.Where(Function(n) n.FirstName.StartsWith(prefixText)).OrderBy(Function(n) n.FirstName).Select(Function(n) n.FirstName).Take(count).ToArray
End Function
Here's the mark-up :
<asp:TextBox ID="TextBox1" runat="server" Width="191px"></asp:TextBox>
<cc1:AutoCompleteExtender ID="TextBox1_AutoCompleteExtender" runat="server"
Enabled="True" minimumprefixlength="1" ServiceMethod ="GetNames" TargetControlID="TextBox1">
</cc1:AutoCompleteExtender>
I wrote the following code to try to get the text box to suggest the full name but it didn't work :
Dim query = (From s In db.Students _
Where s.FirstName.StartsWith(prefixText) _
Order By s.FirstName _
Select New With {.Name = s.FirstName & " " & s.LastName}).Take(count).ToArray
Return query
When I build the project it says "Value of type '1-dimensional array of (line 50)' cannot be converted to '1-dimensional array of String' because ' (line 50)' is not derived from 'String'"
Anyboy has a suggestion, please comment. Thank you.
Don't create a new anonymous object with a name attribute that is a string, just return the string itself:
Dim query = (From s In db.Students _
Where s.firstname.StartsWith(prefixText) _
Order By s.firstname _
Select s.firstname & " " & s.lastname).Take(count).ToArray

Resources