How to control the type of a projection (LINQ to XML)
Projection is the process of filtering a set of data, changing its shape and perhaps its type. Most query expressions do projections. Most of the query expressions in this section evaluate to IEnumerable<T> of XElement, but you can create collections of other types. This article shows how to do this.
Example: Define a new type and create a query that creates an IEnumerable of that type
The following example defines a new type, Customer
, and the query expression instantiates new Customer
objects in the Select
clause. This causes the type of the query expression to be IEnumerable<T> of Customer
. The example uses XML document Sample XML file: Customers and orders.
public class Customer
{
private string customerID;
public string CustomerID{ get{return customerID;} set{customerID = value;}}
private string companyName;
public string CompanyName{ get{return companyName;} set{companyName = value;}}
private string contactName;
public string ContactName { get{return contactName;} set{contactName = value;}}
public Customer(string customerID, string companyName, string contactName)
{
CustomerID = customerID;
CompanyName = companyName;
ContactName = contactName;
}
public override string ToString()
{
return $"{this.customerID}:{this.companyName}:{this.contactName}";
}
}
class Program
{
static void Main(string[] args)
{
XElement custOrd = XElement.Load("CustomersOrders.xml");
IEnumerable<Customer> custList =
from el in custOrd.Element("Customers").Elements("Customer")
select new Customer(
(string)el.Attribute("CustomerID"),
(string)el.Element("CompanyName"),
(string)el.Element("ContactName")
);
foreach (Customer cust in custList)
Console.WriteLine(cust);
}
}
Public Class Customer
Private customerIDValue As String
Public Property CustomerID() As String
Get
Return customerIDValue
End Get
Set(ByVal value As String)
customerIDValue = value
End Set
End Property
Private companyNameValue As String
Public Property CompanyName() As String
Get
Return companyNameValue
End Get
Set(ByVal value As String)
companyNameValue = value
End Set
End Property
Private contactNameValue As String
Public Property ContactName() As String
Get
Return contactNameValue
End Get
Set(ByVal value As String)
contactNameValue = value
End Set
End Property
Public Sub New(ByVal customerID As String, _
ByVal companyName As String, _
ByVal contactName As String)
CustomerIDValue = customerID
CompanyNameValue = companyName
ContactNameValue = contactName
End Sub
Public Overrides Function ToString() As String
Return String.Format("{0}:{1}:{2}", Me.CustomerID, Me.CompanyName, Me.ContactName)
End Function
End Class
Sub Main()
Dim custOrd As XElement = XElement.Load("CustomersOrders.xml")
Dim custList As IEnumerable(Of Customer) = _
From el In custOrd.<Customers>.<Customer> _
Select New Customer( _
el.@<CustomerID>, _
el.<CompanyName>.Value, _
el.<ContactName>.Value _
)
For Each cust In custList
Console.WriteLine(cust)
Next
End Sub
This example produces the following output:
GREAL:Great Lakes Food Market:Howard Snyder
HUNGC:Hungry Coyote Import Store:Yoshi Latimer
LAZYK:Lazy K Kountry Store:John Steel
LETSS:Let's Stop N Shop:Jaime Yorres