Login    
 
 
 
 
Text/HTML
  
You are here :: Blogs Saturday, May 19, 2012

Search
Note: This uses the internal blog search engine. The Google search engine is also available at the top of the page.
  
Disclaimer

Please review the site disclaimer before downloading or using content found on this site

  
Categories
  
DEVSHED Blog
As always, I welcome your comments!
Author: Steve Gray Created: 7/21/2009 8:03 AM RssIcon
Tips and Tricks on LINQ
By Steve Gray on 3/16/2011 3:47 PM

The task here is to take an XML document in this form:

<transfers>
    <transfer transferNumber="TSFR001">
       <timestamp>2011-03-14 11:24:47.077</timestamp>
       <items>
           <item>
               <itemguid>6A639774-5EA9-440C-978B-FDC7DBF71949</itemguid>
               <quantity>1</quantity>
               <fromsite>001</fromsite>
               <tosite>002</tosite>
           </item>
           <item>
               <itemguid>D8FD406F-8CF2-47E6-B09D-E44106153C11</itemguid>
               <quantity>1</quantity>
               <fromsite>001</fromsite>
               <tosite>002</tosite>
           </item>
       </items>
    </transfer>
    <transfer transferNumber="TSFR002">
       <timestamp>2011-03-14 11:24:47.077</timestamp>
       <items>
           <item>
               <itemguid>6A639774-5EA9-440C-978B-FDC7DBF71949</itemguid>
               <quantity>2</quantity>
               <fromsite>001</fromsite>
               <tosite>002</tosite>
           </item>
           <item>
               <itemguid>D8FD406F-8CF2-47E6-B09D-E44106153C11</itemguid>
               <quantity>2</quantity>
               <fromsite>001</fromsite>
               <tosite>002</tosite>
           </item>
       </items>
    </transfer>
</transfers>

And parse it and move it into a class that we can manipulate in VB.

The class structure mirrors the XML document:

Code Snippet
  1. Public Class Transfer
  2.     Public transferNumber
  3.     Public timestamp As DateTime
  4.     Public transferDetail As List(Of TransferDetail)
  5.     Public test As List(Of String)
  6.  
  7. End Class
  8.  
  9. Public Class TransferDetail
  10.     Public itemguid As Guid
  11.     Public quantity As Double
  12.     Public fromsite As String
  13.     Public tosite As String
  14. End Class

Our code loads the XML into an XDocument, and then uses LINQ queries to read it into an instance of the class.

Code Snippet
  1.     Sub example()
  2.         Dim xDoc As XDocument
  3.         Dim eDoc As XElement
  4.         Dim oTransfer As Transfer
  5.         Dim oTransferDetail As TransferDetail
  6.  
  7.         'load an XML document into an xElement type
  8.         eDoc = <transfers>
  9.                    <transfer transferNumber="TSFR001">
  10.                        <timestamp>2011-03-14 11:24:47.077</timestamp>
  11.                        <items>
  12.                            <item>
  13.                                <itemguid>6A639774-5EA9-440C-978B-FDC7DBF71949</itemguid>
  14.                                <quantity>1</quantity>
  15.                                <fromsite>001</fromsite>
  16.                                <tosite>002</tosite>
  17.                            </item>
  18.                            <item>
  19.                                <itemguid>D8FD406F-8CF2-47E6-B09D-E44106153C11</itemguid>
  20.                                <quantity>1</quantity>
  21.                                <fromsite>001</fromsite>
  22.                                <tosite>002</tosite>
  23.                            </item>
  24.                        </items>
  25.                    </transfer>
  26.                    <transfer transferNumber="TSFR002">
  27.                        <timestamp>2011-03-14 11:24:47.077</timestamp>
  28.                        <items>
  29.                            <item>
  30.                                <itemguid>6A639774-5EA9-440C-978B-FDC7DBF71949</itemguid>
  31.                                <quantity>2</quantity>
  32.                                <fromsite>001</fromsite>
  33.                                <tosite>002</tosite>
  34.                            </item>
  35.                            <item>
  36.                                <itemguid>D8FD406F-8CF2-47E6-B09D-E44106153C11</itemguid>
  37.                                <quantity>2</quantity>
  38.                                <fromsite>001</fromsite>
  39.                                <tosite>002</tosite>
  40.                            </item>
  41.                        </items>
  42.                    </transfer>
  43.                </transfers>
  44.  
  45.         'read the xElement into an xDocument. This is the easiest and clearest way to code the example
  46.         xDoc = XDocument.Parse(eDoc.ToString)
  47.  
  48.         'create a collection of xElements
  49.         Dim transferNodes As IEnumerable(Of XElement)
  50.  
  51.         'LINQ query to read the TRANSFERS into our collection
  52.         transferNodes = _
  53.             From el In xDoc.<transfers>.Elements() _
  54.             Select el
  55.  
  56.         'loop through the collection of TRANSFERS
  57.         For Each el As XElement In transferNodes
  58.             'delare a new transfer class
  59.             oTransfer = New Transfer
  60.  
  61.             'initialize the transferDetail Generic.List
  62.             oTransfer.transferDetail = New List(Of TransferDetail)
  63.  
  64.             'assign some of the transfer class properties. Note how we get the transferNumber attribute here
  65.             oTransfer.transferNumber = el.@transferNumber
  66.             oTransfer.timestamp = el.<timestamp>.Value
  67.  
  68.             'the transfer document has childern - items
  69.             'declare a collection of items
  70.             Dim itemNodes As IEnumerable(Of XElement)
  71.  
  72.             'LINQ query to loop through the collection of item elements
  73.             itemNodes = From ie In el.<items>.Elements _
  74.                            Select ie
  75.  
  76.             'loop through the colleciton of ITEMS
  77.             For Each ie As XElement In itemNodes
  78.                 'delcare a new transfer detail class
  79.                 oTransferDetail = New TransferDetail
  80.  
  81.                 'assign some of the class properties
  82.                 oTransferDetail.itemguid = New Guid(ie.<itemguid>.Value)
  83.                 oTransferDetail.quantity = ie.<quantity>.Value
  84.                 oTransferDetail.tosite = ie.<tosite>.Value
  85.                 oTransferDetail.fromsite = ie.<fromsite>.Value
  86.  
  87.                 'add the new transferdetail class to the parent transfer class
  88.                 oTransfer.transferDetail.Add(oTransferDetail)
  89.             Next
  90.         Next
  91.  
  92.  
  93.  
  94.  
  95.     End Sub
  96. End Class
By Steve Gray on 3/15/2011 3:27 PM

This code sample will show you how to take an XML document and parse it into VB elements (in this example I use a class)

First create the class:

Code Snippet
  1. Public Class Item
  2.     Public Property itemnmbr As String
  3.     Public Property itemguid As Guid
  4.     Public Property active As String
  5.     Public Property description As String
  6.     Public Property category As String
  7.     Public Property commissionamt As Double
  8.     Public Property listprice As Double
  9.     Public Property reorderpt As Int32
  10.  
  11. End Class

 

This code will take the XML document shown are read it into the class. You’d want a Generic Collection of this class to get all the items, I’m going for simplicity here as much as possible

Code Snippet
  1. Dim xDoc As XDocument
  2. Dim xElem As XElement
  3.  
  4. xElem = <items>
  5.             <item guid="6A639774-5EA9-440C-978B-FDC7DBF71949">
  6.                 <SKUid>AAA001</SKUid>
  7.                 <active>Y</active>
  8.                 <description>SD128 RAM</description>
  9.                 <category>Electronics</category>
  10.                 <commissionamt>0.00</commissionamt>
  11.                 <listprice>9.99</listprice>
  12.                 <reorderpt>1</reorderpt>
  13.             </item>
  14.             <item guid="D8FD406F-8CF2-47E6-B09D-E44106153C11">
  15.                 <SKUid>AAA02</SKUid>
  16.                 <active>Y</active>
  17.                 <description>SD256 RAM</description>
  18.                 <category>Electronics</category>
  19.                 <commissionamt>0.00</commissionamt>
  20.                 <listprice>19.99</listprice>
  21.                 <reorderpt>5</reorderpt>
  22.             </item>
  23.         </items>
  24.  
  25. xDoc = XDocument.Parse(xElem.ToString)
  26.  
  27. Dim childElements As IEnumerable(Of XElement)
  28.  
  29. childElements = _
  30.     From el In xDoc.<items>.Elements() _
  31.     Select el
  32.  
  33. For Each el As XElement In childElements
  34.     oItem = New Item
  35.     oItem.itemguid = New Guid(el.@guid)
  36.     oItem.itemnmbr = el.<SKUid>.Value
  37.     oItem.active = el.<active>.Value
  38.     oItem.description = el.<description>.Value
  39.     oItem.category = el.<category>.Value
  40.     oItem.commissionamt = el.<commissionamt>.Value
  41.     oItem.listprice = el.<listprice>.Value
  42.     oItem.reorderpt = el.<reorderpt>.Value
  43. Next
By Steve Gray on 2/21/2011 3:24 PM

I’m… just not a big fan of LINQ. It’s hard to work with, the syntax is obscure and it’s hard to find documentation for. I’m not sure if it’s something that will be around in the future.

Anyway, I have this task that reoccurs every so often – given a DataTable, I need to group the table by one (or more) of the fields and do something with the group. Often I need to iterate through the lines in the table that match a group.

Note that the first query returns one field, so when you reference that field in ‘salesQueryItem’, you only need strTo = salesQueryItem. In the second loop there is more than one field in the select, so they’re itemized.

 

Code Snippet
  1. Dim oDT As New DataTable
  2.  
  3. 'create columns
  4. oDT.Columns.Add(New DataColumn("salesperson", System.Type.GetType("System.String")))
  5. oDT.Columns.Add(New DataColumn("order", System.Type.GetType("System.String")))
  6. oDT.Columns.Add(New DataColumn("amount", System.Type.GetType("System.Int16")))
  7.  
  8. 'create the rows
  9. oDT.Rows.Add("Bob@test.com", "ORD00100", 1.23)
  10. oDT.Rows.Add("Bob@test.com", "ORD00102", 3.23)
  11. oDT.Rows.Add("Sam@test.com", "ORD00104", 2.23)
  12. oDT.Rows.Add("Sam@test.com", "ORD00105", 4.23)
  13.  
  14.  
  15. Dim strBody As String = ""
  16. Dim strTo As String = ""
  17. Dim strSubject As String = "Product Hold Email Notification"
  18.  
  19. Try
  20.     Dim salesQuery = From sales In oDT _
  21.                Group sales By salesperson1 = sales("salesperson") Into Group _
  22.                Select salesperson1 = salesperson1
  23.  
  24.  
  25.     For Each salesQueryitem In salesQuery
  26.         strTo = salesQueryitem
  27.         strBody = "Orders for " & strTo & "<br />"
  28.  
  29.         Dim Query2 = From emailNotifications In oDT _
  30.                       Where emailNotifications("salesperson") = strTo _
  31.                       Select order1 = emailNotifications("order"), amount1 = emailNotifications("amount").ToString
  32.  
  33.         For Each Query2item In Query2
  34.             strBody += Query2item.order1 + "<br />"
  35.             strBody += "Amount: " & Query2item.amount1 + "<br />"
  36.         Next
  37.  
  38.         'code to send an email here
  39.     Next
  40.  
  41. Catch ex As Exception
  42.     MsgBox(ex.Message)
  43. End Try
By Steve Gray on 6/17/2010 12:02 PM
I frequently have to read from XML files, the general format of them is something like this:
<eConnect xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <POPReceivingsType>
    <taUpdateCreateVendorRcd>
    </taUpdateCreateVendorRcd>
    <taCreateVendorAddress>
    </taCreateVendorAddress>
    <taPopRcptLineInsert_Items>
      <taPopRcptLineInsert>
        <PONUMBER>PO08/00012</PONUMBER>
        <LOCNCODE>VA-PIEDMONTB</LOCNCODE>
      </taPopRcptLineInsert>
      <taPopRcptLineInsert>
        <PONUMBER>PO08/00012</PONUMBER>
        <LOCNCODE>VA-PIEDMONTA</LOCNCODE>
      </taPopRcptLineInsert>
    </taPopRcptLineInsert_Items>
    <taPopRcptHdrInsert>
      <POPRCTNM>RC08/00028</POPRCTNM>
      <POPTYPE>1</POPTYPE>
    </taPopRcptHdrInsert>
  </POPReceivingsType>
</eConnect>
 
Here’s a simple piece of code that will read the first <taPopRcptLineInsert> node and 
give me the element contained in it. 
In earlier .NET Framework versions I had to set references and include ‘IMPORTS’ 
directives, 4.0 is not requiring that. 

Public Class Form2

    Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles MyBase.Load
        test()
    End Sub

    Private Sub test()
        Dim strPOnumber As String
        Dim strLOCNCODE As String

        Dim doc As System.Xml.Linq.XDocument = _
XDocument.Load(Application.StartupPath & "\xmlfile1.xml")

        Dim query = _
            From c In doc.<eConnect>.<POPReceivingsType>.<taPopRcptLineInsert_Items> _
            Select c.Nodes.First

        For Each g As XElement In query
            strPOnumber = g.<PONUMBER>(0).Value
            strLOCNCODE = g.<LOCNCODE>(0).Value
        Next

    End Sub
End Class
By Steve Gray on 6/3/2010 6:46 AM

Recently I had a project where I needed to have a small configuration file/table that a user could maintain, possibly add records to if needed. The overhead to put that in SQL was a little too much – I’d need to write forms for the maintenance, handle security… it would take a bit to do all that.

Instead, it seemed easier to write an XML file to handle the task and to allow the user FTP access to the web site. So, given an XML file, how do I get access to all the fields in one ‘record’? LinqToXML to the rescue.

First, create a class to represent the record

Public Class eCard
    Public cardID As Int16
    Public image As String
    Public imageThumb As String
    Public subject As String
    Public label As String
End Class

Then, here is code to read the XML file and populate the class. This is a ASP DataList ItemCommand method, the DataList as the ‘cardID’ in the CommandArgument.

Imports System.Data
Imports System.Xml.Linq
Imports System.Linq
Imports System.Xml
    Protected Sub lstCards_ItemCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataListCommandEventArgs) Handles lstCards.ItemCommand
        Dim doc = XDocument.Load(Server.MapPath("/eCards/eCard.xml"))
        Dim cardID As Int16 = e.CommandArgument
        Dim query = _
            From c In doc.<cards>.<card> _
            Where c.<cardID>.Value = cardID _
            Select c
        Dim eCard As New eCard
        For Each g In query
            eCard.cardID = cardID
            eCard.image = g.<image>(0).Value
            eCard.imageThumb = g.<imageThumb>(0).Value
            eCard.subject = g.<subject>(0).Value
            eCard.label = g.<label>(0).Value
        Next
        Session("eCard") = eCard
        Response.Redirect("eCards2.aspx")
    End Sub
By Steve Gray on 8/24/2009 9:16 AM

In a recent project, I needed to sum data in a web page grid and process it on postback.

I could get it into at datatable easily enough, but getting it grouped and summed was stumping me.

Our columns are ITEMNMBR, QUANTITY, LOTNUMBER, DEX_ROW_ID. We’ll group on ITEMNMBR and DEX_ROW_ID. We’ll sum on QUANTITY

So, the data might be:
ITEM1, 5, LOT A, 1001
ITEM1, 6, LOT B, 1001
ITEM2, 1, <NULL>, 1002
ITEM3, 2, <NULL>,1003

Lines 1 and 2 above have the same item number and row id, but 2 different lot numbers.

The final result needs to be:
ITEM1, 11
ITEM2, 1
ITEM3 2

The ‘groupRow’ item in the code below holds a set of rows of the underlying group. In the second section of code we loop through that object. Note that there are two quantity results, the group quantity (11) and the line quantity (5,6)

Here’s the solution. It uses LINQ, so add a reference to SYSTEM.LINQ at the top of the page. Note the use of a system function to do the summing; it’s declared in the second line

Dim oDT As DataTable = gridToDataTable(Me.Grid1)
Dim aggregateSum As System.Func(Of DataRow, Integer) = AddressOf GetSum
Dim data = From c In oDT.AsEnumerable() _
           Group c By itemGroup = c.Field(Of String)("itemnmbr"), _
                dexGroup = c.Field(Of Int32)("dex_row_id") Into Group _
           Select groupRow = Group, _
                itemGroup = itemGroup, _
                quantity = Group.Sum(aggregateSum), _
                dexGroup = dexGroup
 
 
For Each g In data
    strItemnmbr = g.itemGroup
    dblItemSellingQtyReceived = g.quantity
    intDex_row_id = g.dexGroup
 
    For Each n In g.groupRow
        strSerltnum = n("serltnum")
        dblLotSellingQtyReceived = n("quantity")
    Next
Next

The function:

Public Function GetSum(ByVal datarow As DataRow) As Integer
    Return Integer.Parse(datarow("quantity").ToString())
End Function
As always, I welcome your comments!
  
 
 
Home | Products | Blogs | Contact Us | Links | God's Plan
Privacy Statement | Terms Of Use
 
Copyright 2011 by Devshed.us