Professional Documents
Culture Documents
LINQ
LINQ
To enable basic LINQ functionality
Add Reference to System.Core.dl
using directive or Imports statement for System.Linq
To use LINQ to XML
Add a reference to System.Xml.Linq and
System.Data.Linq.Mapping;
Add a using directive or Imports statement for
System.Xml.Linq.
LINQ
Consider simple Query
var query =
from c in Customers
where c.Country == "Italy"
select c.CompanyName;
What is Customers?
SQL database
DataSet
An array of objects
.NET Collection
LINQ
LINQ -SQL
LINQ
Entity
[Table(Name="Customers")]
public class Customer
{
[Column(IsPrimaryKey=true), IsDBGenerated=true]
public string CustomerID;
[Column] public string CompanyName;
[Column] public string City;
[Column(Name="Region")] public string State;
[Column] public string Country;
}
LINQ
Querying into Entity
DataContext db = new DataContext("Database=Northwind");
Table<Customer> Customers = db.GetTable<Customer>();
var query =
from c in Customers
where c.Country == "USA && c.State == "WA"
select new {c.CustomerID, c.CompanyName, c.City };
foreach( var row in query )
{
Console.WriteLine( row );
}
LINQ
We can explore the generated SQL query
Console.WriteLine( db.GetQueryText( query ) );
ie:
SELECT [t0].[CustomerID], [t0].[CompanyName], [t0].[City]
FROM [Customers] AS [t0]
WHERE ([t0].[Country] = @p0) AND ([t0].[Region] = @p1)
An alternative way to get a trace of all SQL statements sent to the
database is to assign a value to the Log property of DataContext:
db.Log = Console.Out;
LINQ
Creating a Derived DataContext Class:
public class SampleDb : DataContext
{
public SampleDb(IDbConnection connection) : base( connection ) {}
public SampleDb(string fileOrServerOrConnection)
: base( fileOrServerOrConnection ) {}
public Table<Customer> Customers;
}
LINQ
Direct Access LINQ Query
Property Accessor User Code
[Column(Storage="_ProductName")]
public string ProductName
{
get
{
return this.ProductName;
}
set
{
this.OnPropertyChanging("ProductName");
this._ProductName = value;
this.OnPropertyChanged("ProductName");
}
}
LINQ
Entity Relations
EntityRef
EntitySet
LINQ
Entity Relation -- EntityRef
[Table(Name="Orders")]
public class Order
{
[Column(IsPrimaryKey=true)] public int OrderID;
[Column] private string CustomerID;
[Association(Storage="_Customer", ThisKey="CustomerID")]
public Customer Customer
{
get { return this._Customer.Entity; }
set { this._Customer.Entity = value; }
}
private EntityRef<Customer> _Customer;
}
LINQ
Querying
Table<Order> Orders = db.GetTable<Order>();
var query =
from o in Orders
where o.Customer.Country == "USA"
select o.OrderID;
var query =
from o in Orders
where o.OrderID == 10528
select o;
foreach( var row in query )
{
Console.WriteLine( row.Customer.Country );
}
LINQ
EntitySet
[Table(Name="Customers")]
public class Customer
{
[Column(IsPrimaryKey=true)] public string CustomerID;
[Column] public string CompanyName;
[Column] public string Country;
[Association(OtherKey="CustomerID")]
LINQ
EntitySet
[Table(Name="Customers")]
public class Customer
{
[Column(IsPrimaryKey=true)] public string CustomerID;
[Column] public string CompanyName;
[Column] public string Country;
[Association(OtherKey="CustomerID", Storage="_Orders")]
public ICollection<Order> Orders
{
get { return this._Orders; }
set { this._Orders.Assign(value);
}
private EntitySet<Order> Orders;
LINQ
Querying Ex(1)
Table<Customer> Customers = db.GetTable<Customer>();
var query =
from c in Customers
where c.Orders.Count > 20
select c.CompanyName;
Querying Ex(2)
var query =
LINQ
from c in Customers
where c.Orders.Count > 20
select c;
LINQ
Querying Ex(2)
from c in Customers
where c.Orders.Count > 20
select c;
LINQ
Querying Ex(2)
LINQ
Querying Ex(3)
from c in Customers
where c.Orders.Count > 5
select c;
DisplayTop( query, 10 );
from c in query
where c.Country == "USA"
select c;
DisplayTop( query, 10 );
LINQ
Querying the Details Table
IEnumerable<Order> orders = db.Customers
.Where(c => c.Country == "USA" && c.Region == "WA")
.SelectMany(c => c.Orders);
foreach(Order item in orders)
Console.WriteLine("{0} - {1} - {2}",
item.OrderDate, item.OrderID, item.ShipName);
LINQ
Querying on Primary Key
var customer = db.Customers.Single( c => c.CustomerID == "ANATR" );
Console.WriteLine( "{0} {1}", customer.CustomerID,
customer.CompanyName );
LINQ
LINQ - Joins
var queryJoin =
from p in db.Products
join o in db.Order_Details
on p.ProductID equals o.ProductID
into OrdersProduct
where p.ProductName == "Chocolade"
select OrdersProduct.Sum( o => o.Quantity );
var quantityJoin = queryJoin.Single();
Console.WriteLine( quantityJoin );
Console.WriteLine( quantityValue );
LINQ
Stored Procedures
Making a CALL
LINQ
Stored Functions
Making a CALL
var query =
from c in Categories
select new
{
c.CategoryID, c.CategoryName,
MinPrice =
db.MinUnitPriceByCategory( c.CategoryID )
};
Making a CALL
Table<Order> Orders = db.GetTable<Order>();
var queryCustomers =
from c in db.CustomersByCountry( "USA" )
join o in Orders
on c.CustomerID equals o.CustomerID
into orders
select new { c.CustomerID, c.CompanyName, orders };
LINQ
Data Manipulation
Entity Updates
FROM
FROM
FROM
FROM
Conflict Handling
DataContext has Refresh() function with following Enumerated
Parameter Values
KeepChanges
KeepCurrentValues
OverwriteCurrentValues
Conflict Handling
Each Column attribute can have an UpdateCheck argument that can
have one of the following three values:
Always Always use this column (which is the default) for conflict
detection.
Never Never use this column for conflict detection.
WhenChanged Use this column only when the member has been
changed by the application
Involving Transactions
using(TransactionScope ts = new TransactionScope())
{
Product prod = db.Products.Single
(p => p.ProductID == 42);
if (prod.UnitsInStock > 0)
prod.UnitsInStock--;
db.SubmitChanges();
ts.Complete();
LINQ
LINQ-DataSet
Querying DataSet
DataSet ds = LoadDataSetUsingDataAdapter();
DataTable orders = ds.Tables["Orders"];
DataTable orderDetails = ds.Tables["OrderDetails"];
var query =
from o in orders.AsEnumerable()
where o.Field<DateTime>( "OrderDate" ).Year >= 1998
orderby o.Field<DateTime>( "OrderDate" ) descending
select o;
LINQ-Join
DataSet ds = LoadDataSetUsingDataAdapter();
DataTable orders = ds.Tables["Orders"];
DataTable orderDetails = ds.Tables["OrderDetails"];
var query =
from o in orders.AsEnumerable()
join od in orderDetails.AsEnumerable()
on o.Field<int>( "OrderID" ) equals od.Field<int>( "OrderID" )
into orderLines
where o.Field<DateTime>( "OrderDate" ).Year >= 1998
orderby o.Field<DateTime>( "OrderDate" ) descending
select new { OrderID = o.Field<int>( "OrderID" ),
OrderDate = o.Field<DateTime>( "OrderDate" ),
Amount = orderLines.Sum(
};
LINQ
LINQ-XML
TypeCast
XElement order = new XElement("order",
new XElement("quantity", 10),
new XElement("price", 50),
new XAttribute("idProduct", "P01"));
Decimal orderTotalAmount =
(Decimal)order.Element("quantity") * (Decimal)order.Element("price");
Console.WriteLine("Order total amount: {0}", orderTotalAmount);
Explicit Escaping
XElement notes = new XElement("notes", "Some special characters like & > < <div/>
etc.");
The result is encoded automatically using XmlConvert and looks like the following:
<notes>Some special characters like & > < <div/> etc.</notes>
LINQ
Reading XML
Thru LINQ
var customersFromXml =
from c in xmlCustomers.Elements("customer")
where (String)c.Attribute("country") == "Italy"
orderby (String)c.Element("name")
select new
{ Name = (String)c.Element("name"),
City = (String)c.Attribute("city")
};
foreach (var customer in customersFromXml)
{
Console.WriteLine(customer);
}
The result is shown in the following output block:
{ Name = Marco, City = Torino }
{ Name = Paolo, City = Brescia }
IEnumerable<XElement> tests =
from el in root.Elements("Test")
where (string)el.Element("CommandLine") == "Examp2.EXE"
select el;
foreach (XElement el in tests)
Console.WriteLine((string)el.Attribute("TestId"));
var titles =
from book in books.Elements("book")
where (string) book.Element("author") == "Joe Rattz"
select book.Element("title");
foreach(var title in titles)
Console.WriteLine(title.Value);