Many times we need to get the Public key token for a strongly named assembly in .NET. FAQ on that “how to get the public key token?”. Answer is very simple use the .NET Framework tools sn.exe. So open the Visual Studio 2008 Command Prompt and then point to the dll’s folder you want to get the public key,
Use the following command,
sn –T myDLL.dll
This will give you the public key token. Remember one thing this only works if the assembly has to be strongly signed.
Example
C:\WINNT\Microsoft.NET\Framework\v3.5>sn -T EdmGen.exe
Microsoft (R) .NET Framework Strong Name Utility Version 3.5.21022.8
Copyright (c) Microsoft Corporation. All rights reserved.
Public key token is b77a5c561934e089
Namoskar!!!
For small blogs, it requires more references and explanation, which sometimes are redundant. So I thought of writing single blog which is combination of topics more or less related to one thing.
I am exploring ADO.NET Entity Framework and have been trying things out there. Here I am planning to demonstrate how to do insert, update and delete.
Here I will use a database created by me.
Now I will create TestDB.edmx out of this database.
Insert
using (TestDBEntities ctx = new TestDBEntities())
{
//Create new Emp object
Emp e = new Emp() { Name = "Test Employee" };
//Add to memory
ctx.AddToEmp(e);
//Save to database
ctx.SaveChanges();
}
Update
//Get the specific employee from Database
Emp e = (from e1 in ctx.Emp
where e1.Name == "Test Employee"
select e1).First();
//Change the Employee Name in memory
e.Name = "Changed Name";
Delete
//Delete it from memory
ctx.DeleteObject(e);
In my next post I will write about “how to handle CRUD with Relationship”.
As usual Express editions are free but this time you can take this and sit in a remote location and install Visual Studio with no Internet connections. Yes we can download offline .iso to avoid download & install pain.
Please visit, http://www.microsoft.com/express/download/offline.aspx
After downloading you can write them in DVD. This version includes all the Express Editions.
So enjoy with this light-weight Visual Studio 2008 and have the magic. You can also install .iso by creating virtual drive by using utility such as Daemon.
LINQ to SQL uses optimistic concurrency be default. LINQ to SQL is pure in memory operation, because you normally get the data from database and store them in .NET memory and perform some pure in memory update to those objects and finally when you are done with your modification you give those data back to the database. But what if someone changes the data in between; this is quite possible in network scenario. The default behavior in LINQ to SQL is that whoever hits the database wins the race. This is called optimistic concurrency. You can implement pessimistic concurrency with the new Transaction in .NET 3.0.
Let’s check it out
I have a table
Emp
Id int
Name varchar(50)
Let’s have some dummy data,
Id Name
1 C# 1.0
2 C# 2.0
3 C# 3.0
4 Orcas
Now I want to play with the Id = 4, and modify as per the condition.
Need this basic,
[Table(Name="Emp")]
public class Emp
[Column(IsPrimaryKey=true, IsDBGenerated=true)]
public int Id { get; set; }
[Column]
public string Name { get; set; }
public class TestDB : DataContext
public Table<Emp> Emps;
public TestDB(string s):base(s){}
Now using this code I will write an application to update data in the database.
static void Main(string[] args)
Console.Title = "LINQ to SQL Demo";
string sConn = @"Database connection string";
TestDB db = new TestDB(sConn);
ObjectDumper.Write(db.Emps);
//Get the element you want to modify
var query = db.Emps.First(e => e.Id == 4);
//Update the memory object
if (query.Name == "Orcas")
query.Name = "Visual Studio 2008 Beta 2";
else
query.Name = "Orcas";
//Just wait for other application to make changes
//this is intetional as we need to throw an error
Console.WriteLine("Ready to edit. Press any key..");
Console.Read();
//Update the database
db.SubmitChanges();
//Show the changed value
Now if you compile and run this app in two different command window and both of them will come and wail with the line, “Ready to Edit. Press any key to continue..”.
Whichever you click first will update the data and the second one will throw you and error.
Unhandled Exception: System.Data.Linq.ChangeConflictException: Row not found or changed.
This is optimictic concurrency, who executes first wins the race and other fails because there is a conflict in the actual source and the in memory data which you are modifying.
Now if you inplement the same code with TransactionScope class which is new in .NET Framework 2.0.
string sConn = @"Database connection";
//This new Transaction class in .NET Framework 3.0
using (TransactionScope ts = new TransactionScope())
Console.WriteLine("Ready to edit.Press any key..");
//Complete the Transaction
ts.Complete();
This again uses the same behavior but with managed scope. Especially when you have multiple update happening and the error is more tempting I must say,
Unhandled Exception: System.Data.SqlClient.SqlException: Transaction (Process ID 52) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
No one likes to be a deadlock victim.
LINQ to SQL support updating data through object. Continuing with my previous blog on INSERT, let me discuss about the update method
string strConnection = @"Connection String";
TestDB db = new TestDB(strConnection);
//Here I am finding the employee with Id 19
var updateQ = db.Emps.First(e => e.Id == 19);
//Then I will modify that employee name and give new name
updateQ.Name = "Updated Employee";
//Commit the changes to database
//at this point DML gets generated
//To view the updated data
All the methods are coming from DataContext class (responsible for SQL query generation). The above method converts the object addition to DML query.
ADO.NET is our contemporary data access component and now we have written many applications. Now there has been a lot of talk on LINQ to SQL. So we are little skeptical about this component and trying to find some relation between existing ADO.NET technology.
Purpose of this post is to give some quick brief on some major differences between ADO.Net and LINQ to SQL. I have not used 100% code as this is just to give an idea. The database I have used here is Northwind (SQL Server 2000 Sample database).
Some comparison,
Scenario 1
+++++++
Establishing connection between database and application,
ADO.NET
using(SqlConnection conn = new SqlConnection("Connection String"))
conn.Open();
LINQ to SQL
You create a .dbml file and give a name (assume “NW.dml”). Then there will be a DataContext class created. So you need to initialize the instance of an object.
NWDataContext db = new NWDataContext("Connection String");
You do not need to call any Open() method. Datacontext handles well the open and close method.
Scenario 2
Getting data from database,
using (SqlCommand comm = new SqlCommand("Select * from Customers"))
SqlDataReader reader = comm.ExecuteReader();
DataTable dt = new DataTable("New Table");
dt.Load(reader);
using (NorthwindDataContext db = new NorthwindDataContext())
//You can also use "var" at "IEnumerable<Customer>"
IEnumerable<Customer> custs = from c in db.Customers
select c;
foreach (Customer c in custs)
Console.WriteLine(c.CompanyName);
WOW!!! I have received comment from our Senior Program Manager Dinesh Kulkarni from LINQ to SQL team when I requested him to visit my blog. He mentioned,
DataTable provides you a cache that can be re-enumerated without DB roundtrip while LINQ to SQL results need to be explicitly cached with something like a ToList()/ToArray(). Identity caching in DataContext aside, the L2S code is closer to enumerating a DataReader. Although DataReader does not allow you to re-enumerate and requires another ExecuteReader, the impact of reenumerating L2S query is the same – another roundtrip to DB.
Inserting into the database,
using(SqlConnection conn = new SqlConnection())
SqlCommand comm = new SqlCommand("INSERT INTO...", conn);
comm.ExecuteNonQuery();
//Create a new object
Customer c = new Customer();
c.CustomerID = "ABCDE";
//.... add all the properties you need to add while inserting
//Add it to the collection
db.Customers.InsertOnSubmit(c);
//Save the changes to the database
Scenario 4
Updating database,
Same as Scenario 3
//Get the object from database
Customer cust = (from c in db.Customers where c.CustomerID == "ALFKI" select c).First();
//Update the exsisting value
cust.CompanyName = "I do not know?";
Scenario 5
Deleting records from the database,
//Remove it from collection
db.Customers.DeleteOnSubmit(cust);
Executing stored proc which returns record(s),
using (SqlCommand comm = new SqlCommand("SalesByCategory", conn))
comm.CommandType = CommandType.StoredProcedure;
comm.Parameters.AddWithValue("@param1", "value1");
comm.Parameters.AddWithValue("@param2", "value2");
In LINQ to SQL it becomes metod as you drag and drop it to .dbml file,
var outPut = db.SalesByCategory("SeaFood", "1998");
Performance of LINQ to SQL and ADO.NET
LINQ to SQL Performance Part 1
LINQ to SQL Performance Part 2
LINQ to SQL Performance Part 3
LINQ to SQL Performance Part 4
LINQ to SQL Performance Part 5
There are a many to discuss. Hope you have enjoyed it.
There are many more books available. Go and grab them
· Acceptance Test Engineering Guidance
· Application Architecture Guidance
· Common Service Locator
· Composite Application Guidance for WPF
· Design for Operations
· Enterprise Library
· ESB Guidance
· GAX Extensions Library
· Guidance Explorer
· Performance Testing Guidance for Web Applications
· Performance Testing Guidance Project
· SharePoint Development Guidance
· Smart Client Guidance
· Team Development with Visual Studio Team Foundation Server
· Unity Application Block
· VSTS Guidance Project
· WCF Security Guidance
· Web Client Software Factory
· Web Service Software Factory
More http://msdn.microsoft.com/hi-in/practices/bb190344(en-us).aspx
When we work with relational database and especially when with larger data we generally go for custom paging. This allows us to create superfast application.
The simple logic for paged query is like,
Let’s suppose you have 100 rows. Now you want to get data of page size 10 for page 2.
So the starting record would be
StartRecord = (PageNumber – 1) * PageSize
For page 2 it would be
StartRecord = (2 – 1) * 10 = 10 (may be you need to +1 to skip one record)
Now when this comes to LINQ to SQL scenario remains the same where the implementation is little different.
NorthWindDataContext db = new NorthWindDataContext();
var query = from c in db.Customers
select c.CompanyName;
//Assuming Page Number = 2, Page Size = 10
int iPageNum = 2;
int iPageSize = 10;
var PagedData = query.Skip((iPageNum - 1) * iPageSize).Take(iPageSize);
ObjectDumper.Write(PagedData);
Generated T-SQL,
For SQL Server 2000 the provider does not support Skip().
For SQL Server 2005
===================
SELECT [t1].[CompanyName]FROM ( SELECT ROW_NUMBER() OVER (ORDER BY [t0].[CompanyName]) AS [ROW_NUMBER], [t0].[CompanyName] FROM [dbo].[Customers] AS [t0] ) AS [t1]WHERE [t1].[ROW_NUMBER] BETWEEN @p0 + 1 AND @p0 + @p1ORDER BY [t1].[ROW_NUMBER]-- @p0: Input Int (Size = 0; Prec = 0; Scale = 0) [10]-- @p1: Input Int (Size = 0; Prec = 0; Scale = 0) [10]-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.30428.1
Few days back I had written an article on Insert/Update/Delete for simple standalone tables at ADO.NET Entity: Insert Update and Delete. Now after that many of you had requested me to put article on how it works with relationship.
Here I will use a database created by me. There will be two tables connected with each other.
//Create new Department
Dept d = new Dept() { DeptName = "ADO Entity" };
//Create new Employee 1
EmpDept ed1 = new EmpDept() { EmpName = "ADO Employee 1" };
//Create new Employee 2
EmpDept ed2 = new EmpDept() { EmpName = "ADO Employee 2" };
//Add employee to the Dept *OBJECT*
d.EmpDept.Add(ed1);
d.EmpDept.Add(ed2);
//Updating the context
ctx.AddToDept(d);
//Save to Database
//Get an existing Department
Dept dep = (from d in ctx.Dept
where d.DeptId == 22
select d).First();
//Set new Department name
dep.DeptName = "ADO.NET 3.0";
EmpDept ed2 = new EmpDept() { EmpName = "ADO 2" };
//Add *new* employee to the Dept *OBJECT*
dep.EmpDept.Add(ed2);
Dept dep = (from d in ctx.Dept.Include("EmpDept")
/*
Needd to do ToList() becuase once you delete
a record then iteration will not be possible.
*/
foreach (EmpDept ed in dep.EmpDept.ToList())
//This removes relationship from Context
dep.EmpDept.Remove(ed);
//Delete it from context
ctx.DeleteObject(ed);
//Delete the master table
ctx.DeleteObject(dep);
Note: during delete you first need to remove the relationship from entity and then delete the object from entity. So you need to keep the child data offline and then do operation. Then delete the main object.
In my next post I will write about “how to select with Relationship”.
LINQ to SQL designer in Visual Studio allows us to create mapped class using the drag and drop feature from Server Explorer. Now that is business object which ideally you could use as your datasource and from Visual Studio 2008. So let us have this step by step,
Open your Visual Studio 2008 and create a new Windows Forms application (assume C#).
Now add new item to the project LINQ to SQL (.dbml). Give name NW.dbml.
Open a new Data Connection from your VS 2008’s Server Explorer window.
Point to Northwind database. Drag and drop Customers and Orders table. Since Customer and Order table has one to many relationship the designer will get generated like below,
Now open a data source from Data menu of your VS 2008. Click on add new Datasource. Add object DataSource.
Now click on next, choose Customer.
Click next and finish.
Now your datasource window will show both Customer and Order because they are connected through PK/FK.
Make Customer as details view
Drag Customer to your Windows Forms. Then all the navigator and grid will be created as the RAD (Rapid Application Development).
Now you also drag and drop Orders (this will create DataGrid). Now a add the code to your form_load event.
private void Form1_Load(object sender, EventArgs e)
NWDataContext db = new NWDataContext();
this.customerBindingSource.DataSource = db.Customers;
Final look,
Relationship and getting data from Entity Framework using Northwind database
Simple Query
using (NorthwindEntities ctx = new NorthwindEntities())
var query = from o in ctx.Orders
select o.OrderID;
foreach (var k in query)
Console.WriteLine(k);
Now if you want to filter this with the parent information,
where o.Customers.City == "London"
This actually goes one level up and then filters the data.
Include Child Information
var query = from c in ctx.Customers
where c.City == "London"
Console.WriteLine(k.ContactName);
Now if you want to get the “Orders” table, there are two ways to do it,
Immediate Loading
var query = from c in ctx.Customers.Include("Orders")
Console.WriteLine(k.Orders.Count);
On-Demand Loading
//if not loaded then load it
if (!k.Orders.IsLoaded)
k.Orders.Load();
LINQ is not just for the developers who used to write queries for databases but also for the Functional Programmers. So do not worry if you are not very comfortable with SQL kind of queries, we have a very nice option called “Lambda Expression”. Here I am going to demonstrate the scenario for both the options with a small example. This example has an array of integers and I am only retrieving the even numbers using the power of LINQ. Here we go
using System;
using System.Collections.Generic;
using System.Text;
using System.Query;
using System.Xml.XLinq;
using System.Data.DLinq;
namespace LINQConsoleApplication1
class Program
int[] arrInt = {1,2,3,4,5,6,7,8,9,10};
#region Place to change
//Language Integrated Query
var aa = from s in arrInt
where s % 2 == 0
select s;
#endregion
foreach (var item in aa)
Console.WriteLine("{0}", item);
Console.ReadKey();
If you do not want to use the different approach of query for Language then you are free to use Lambda Expression. So just replace the #region area with the following code block results will be identical.
//Lambda Expression
var aa = arrInt.Where(s => s % 2 == 0);
Output will look like
Output
=====================
2
4
6
8
10
Namoskar
Applied to: Visual Studio 2005 [C#]
Yes this is Generics. The concept which helps us to create collection easily and elegantly. Two steps to create the list is demonstrated here.
Step 1:
You have one object say for list of products which contains three properties Name, Quantity and Price.
namespace MSDN_Generics
class Product
private int _Quantity;
public int Quantity
get { return _Quantity; }
set { _Quantity = value; }
private int _Price;
public int Price
get { return _Price; }
set { _Price = value; }
private string _Name;
public string Name
get { return _Name; }
set { _Name = value; }
/// <summary>
/// Constructor to initialize the class
/// </summary>
/// <param name="sName"></param>
/// <param name="iQty"></param>
/// <param name="iPrice"></param>
public Product(string sName, int iQty, int iPrice)
_Name = sName;
_Quantity = iQty;
_Price = iPrice;
Step 2: Create a List of this class to use it for DataGridView’s datasource.
List<Product> myProds = new List<Product>();
myProds.Add(new Product("Prod 1", 1, 1));
myProds.Add(new Product("Prod 2", 2, 2));
myProds.Add(new Product("Prod 3", 3, 3));
myProds.Add(new Product("Prod 4", 4, 4));
myProds.Add(new Product("Prod 5", 5, 5));
myProds.Add(new Product("Prod 6", 6, 6));
myProds.Add(new Product("Prod 7", 7, 7));
dataGridView1.DataSource = myProds;
You need a namespace reference to use this Generic listing System.Collections.Generic
LINQ to XML API allows us to create complete XML document as expected with all the elements. So this X-DOM has everything as you expect.
Simple sample looks like,
XDocument doc = new XDocument(
new XDeclaration("1.0", "utf-16", "true"),
new XProcessingInstruction("test", "value"),
new XComment("This is comment by you"),
new XElement("Employees",
new XElement("Employee",
new XAttribute("id", "EMP001"),
new XElement("name", "Wriju"),
new XCData("~~~~~~~XML CDATA~~~~~~~~"))));
By calling Save method of XDocument (actually of XContainer) you can save it to a physical file. And the file will look like,
<?xml version="1.0" encoding="utf-16" ?>
<?test value?>
<!-- This is comment by you -->
<Employees>
<Employee id="EMP001">
<name>Wriju</name>
<![CDATA[ ~~~~~~~XML CDATA~~~~~~~~]]>
</Employee>
</Employees>
To me this looks like more aligned to the human thinking mechanism.
Last week I was exploring VB.NET for the ISV demo delivery. Some findings I want to share with you. First the object and Array Initializers
Let’s suppose we have a class called Customer
Public Class Customer
Public Id As Integer
Public Name As String
End Class
Now when you initialize this object in conventional VB.NET, this could be your approach,
Dim cust As New Customer()
With cust
.Id = 1
.Name = "VB.NET"
End With
Now in VB.NET 9.0 we do things in little differently,
Dim cust = New Customer() With {.Id = 2, .Name = "VB.NET 9.0"}
Also for array initialization in VB.NET we go for,
Dim objCusts(1) As Customer
objCusts(0) = New Customer() With {.Id = 3, .Name = "VB.NET 10.0"}
objCusts(1) = New Customer() With {.Id = 4, .Name = "VB.NET 11.0"}
In VB.NET 9.0 we write,
Dim objCusts() As Customer = { _
New Customer() With {.Id = 3, .Name = "VB.NET 10.0"}, _
New Customer() With {.Id = 4, .Name = "VB.NET 11.0"}}
It is small (to me simple), it is sweet.
LINQ to SQL executes or generated SQL statement only when you run a foreach statement or you perform to ToList() method to it. If you need to display the output multiple times without executing the real database query, you can store them in memory. This can be done only when you are sure that the data is static.
Let’s suppose,
//This takes the connection string from file Settings.settings
//which gets generated while creating Linq to Sql (.dml) file
NorthwindDBDataContext db = new NorthwindDBDataContext();
db.Log = Console.Out;
//Get the Customers from database
//This point the query gets executed
foreach (var c in query)
//This point the query AGAIN gets executed
The output will look like
SELECT [t0].[CustomerID], [t0].[CompanyName], [t0].[ContactName], [t0].[ContactT
itle], [t0].[Address], [t0].[City], [t0].[Region], [t0].[PostalCode], [t0].[Coun
try], [t0].[Phone], [t0].[Fax]
FROM [dbo].[Customers] AS [t0]
WHERE [t0].[City] = @p0
-- @p0: Input NVarChar (Size = 6; Prec = 0; Scale = 0) NOT NULL [London]
SqlProvider\AttributedMetaModel
Around the Horn
Consolidated Holdings
Eastern Connection
North/South
Seven Seas Imports
Now when I am sure that my data is not changing there is no point again going back to the database and execute the data for another operation. Rather what I can do is that I can cache the output and store them in some object.
Now if I execute the code like,
var listCusts = query.ToList();
//This point the query does not get executed
foreach (var c in listCusts)
Console.WriteLine("+++++");
//This point the query ALSO does not get executed
Now the output will look like,
+++++
Isn’t it better???
We have seen how to create the XML content from raw data initializing elements and attributes one by one. More realistic approach in the world of application development would be to read the values either from relational database or collection. Let’s use the combined power of LINQ and XLinq to create XML content easily and smartly.
Using C# 3.0 enhancement, implicitly typed array which is the combination of anonymous object initializers to create the anonymously typed data structures.
My famous Customers object, defined
var objCust = new[]
new {CustID = 2, CustName = "Sumitra", Phone = "123-123-1236"},
new {CustID = 3, CustName = "Wriju", Phone = "123-123-1235"},
new {CustID = 4, CustName = "Writam", Phone = "123-123-1234"},
new {CustID = 1, CustName = "Debajyoti", Phone = "123-123-1237"}
};
Now we will create XML out of it with proper order (notice that the CustID is not in proper sequence). We can filter the data with the help of LINQ.
XElement _customers = new XElement("customers",
from c in objCust
orderby c.CustID //descending
select new XElement("customer",
new XElement("name", c.CustName),
new XAttribute("ID", c.CustID),
new XElement("phone", c.Phone)
)
);
Console.WriteLine(_customers);
The output will look like.
<customers>
<customer ID="1">
<name>Debajyoti</name>
<phone>123-123-1237</phone>
</customer>
<customer ID="2">
<name>Sumitra</name>
<phone>123-123-1236</phone>
<customer ID="3">
<phone>123-123-1235</phone>
<customer ID="4">
<name>Writam</name>
<phone>123-123-1234</phone>
</customers>
Isn’t it cool!!!! Yes, yes, yes….
We can generate hierarchical object graph in our memory though LINQ. To be more realistic we can bring data from relational database. So if we consider Northwind database and use LINQ to SQL to bring all the Customers and their Orders and Order Details the query would look like,
//LINQ to SQL way to get data from database
var q = from c in db.Customers
select new
CId = c.CustomerID,
Orders = from o in c.Orders
OID = o.OrderID,
Qty = from od in o.Order_Details
select new { Qty = od.Quantity }
So what I am trying to do here is that, I am trying to fetch CustomerId from Customers table and OrderId from Orders table and Quantity from Order Details table. It is bringing 3 level deep data for me and storing it to memory.
By using XElement and XAttribute I will create a single XML stream. Which will look like,
<?xml version="1.0" encoding="utf-8"?>
<customer id="ALFKI" country="Germany" contactName="Maria Anders" contactTitle="Sales Representative">
<Orders id="10643" date="1997-08-25T00:00:00">
<items>
<item price="45.6000" quantity="15" />
<item price="18.0000" quantity="21" />
<item price="12.0000" quantity="2" />
</items>
</Orders>
<Orders id="10692" date="1997-10-03T00:00:00">
<item price="43.9000" quantity="20" />
…….
To achieve this I have to write a very simple query like syntax based on the query I have written earlier,
var query = new XElement("customers",
from c in db.Customers
select
new XElement("customer",
new XAttribute("id", c.CustomerID),
new XAttribute("country", c.Country),
new XAttribute("contactName", c.ContactName),
new XAttribute("contactTitle", c.ContactTitle),
from o in c.Orders
select new XElement("Orders",
new XAttribute("id", o.OrderID),
new XAttribute("date", o.OrderDate),
new XElement("items",
from od in o.Order_Details
select new XElement("item",
new XAttribute("price", od.UnitPrice),
new XAttribute("quantity", od.Quantity))))));
It looks complex because it is one liner but actually it is very simple. This will give you the exact XML output mentioned earlier.
LINQ to SQL support deleting data through object. Continuing with my previous blog on INSERT, let me discuss about the delete method
//Here I am finding the employee with Id 18
//You can get an error if id does not exists
var deleteQ = db.Emps.First(e => e.Id == 18);
//Delete the specific entry from collection
db.Emps.Remove(deleteQ);
Now the line db.Log = Console.Out; gives me the SQL query generated by the background engine.
DELETE FROM [Emp] WHERE ([Name] = @p0) AND ([Id] = @p1)
SELECT
(CASE
WHEN (@@ROWCOUNT) > 0 THEN @@ROWCOUNT
ELSE (
SELECT -1
WHERE NOT (EXISTS(
SELECT NULL AS [EMPTY]
FROM [Emp] AS [t1]
WHERE [t1].[Id] = @p2
))
END) AS [value]
-- @p0: Input NVarChar (Size = 6; Prec = 0; Scale = 0) NOT NULL [Writam]
-- @p1: Input Int (Size = 0; Prec = 0; Scale = 0) NOT NULL [18]
-- @p2: Input Int (Size = 0; Prec = 0; Scale = 0) NOT NULL [18]
IEnumerable<T> and IQueryable<T> are the two most used terms of any LINQ discussion. What I am trying to here is that I am trying to simplify the two interfaces depending on their behavior. In LINQ world we generally have few providers available within .NET Framework, like LINQ to Object, LINQ to SQL, LINQ to XML.
It is a statement that every LINQ statement returns IEnumerable<T>. IEnumerable works in steps. Meaning, when you write,
var q = from a in b
where a > 5
select a;
It creates a list out “b” depending on “where” then it creates another list for “select”. This is the behavior of LINQ to Object and LINQ to XML.
When you use LINQ to SQL it uses IQueryable<T>. This interface inherits from IEnumerable<T> but typically any LINQ to SQL generates T-SQL at the backend to be able to get the data for us. This evaluate and generates the query at one shot and gives us the whole data.
Installing Team Foundation Server 2010 is as easy as Microsoft Office Installation. This is my second attempt to install single server TFS 2010. I am successful again.
Few things we need to take care is
1. Use the Team Foundation Server 2010 Installation Guide and follow it step by step at http://www.microsoft.com/downloads/en/details.aspx?FamilyID=2d531219-2c39-4c69-88ef-f5ae6ac18c9f&displaylang=en
2. I had to ensure that it has IIS and .NET Framework installed from Server Role.
3. I had installed Windows Server 2008 R2 and then installed SQL Server 2008 R2 Standard. I have installed it with all the component including SSRS and SSAS.
4. Then I downloaded and installed Windows SharePoint Services 3.0 x64 with Service Pack 2 from http://go.microsoft.com/fwlink/?LinkId=148457. Follow the instruction.
5. Finally I installed Team Foundation Server 2010
Once the TFS 2010 Installation is complete it asks for the configuration
Configure the Proxy
Then Build service
Last thing is the Sharepoint. Once over you are ready to go. What is most important is the easily approach and we do not have to think about it. Enjoy the ALM via Team Foundation Server 2010.
LINQ to SQL is object relational model and .dbml file generates the class file for all kind of Create, read, update and delete (CRUD) through the mapping mechanism. Ideally this should allow us to enable it for WCF Service. But for that we have to manually add DataContract and DataMember attributes. We can use .dbml’s designer feature to add those to our code.
Simply right click on the dbml designer and press F4 to get the property window, you will get a property “Serialization Mode”. Set it to “Unidirectional”. That’s all. This is simple but very helpful.
Now your DataContext and Properties will have the following attributes,
[DataContract()]
[DataMember(Order=n)]
Wherever required. *n indicates the sequence.
You have XML document now you want to modify that XML file using LINQ to XML. It is as easy as you generally modify any database column value.
Let us create a dummy XML stream,
//Create dummy XML to work
var root = new XElement("parent",
from i in new int[] { 1, 2, 3, 4, 5, 6 }
select new XElement("child",
new XAttribute("number", i)));
This will create XML like,
<parent>
<child number="1" />
<child number="2" />
<child number="3" />
<child number="4" />
<child number="5" />
<child number="6" />
</parent>
Let us play with this XML file,
//Get the element (child3)
XElement child3 = root.Descendants("child").First(
el => (int)el.Attribute("number") == 3);
//Add element before the child3
child3.AddBeforeSelf(new XElement("child25"));
//Add sub-element to the child3
child3.Add(new XElement("grandchild"));
//Add element after the child3
child3.AddAfterSelf(new XElement("child35"));
//Add attribute to the child3
child3.Add(new XAttribute("attr", "something"));
//Change the existing attribute
child3.SetAttributeValue("number", 100);
After all these activities you will get the following output,
<child25 />
<child number="100" attr="something">
<grandchild />
</child>
<child35 />
Highlighted part is the modified portion of your XML. You can also remove an element,
child3.Remove();
I was going through the document on LINQ Project Overview then got interested to an example there at page 14. The amazing feature of GroupBy, programming will become the communication language one I am sure. We will have lingo, dialects, accent etc. I am excited to share the logic mentioned there (commented for better understanding)
Assume that you have an array containing the names. You are not sure the length of the names. You have given assignment to provide output that will show the names with equal length together. Hummm LINQ the easy approach of life,
namespace LINQConsoleApplication1_Oct10
//Declare the String Array
string[] names = {"Albert", "Burke", "Connor", "David",
"Everett", "Frank", "George", "Harris"};
//Defining the GroupBy logic (here it is lengthwise)
var groups = names.GroupBy(s => s.Length);
//Iterate through the collection created by the Grouping
foreach(IGrouping<int, string> group in groups)
//Branch on the condition decided
Console.WriteLine("Strings of Length {0}", group.Key);
//Actual results
foreach(string value in group)
Console.WriteLine(" {0}", value);
Strings of Length 6
Albert
Connor
George
Harris
Strings of Length 5
Burke
David
Frank
Strings of Length 7
Everett
XElement and XAttribute are the two very important classes available in System.Xml.Linq.dll assembly. Using these two classes you can do lot of things in the LINQ to XML world. I will show you step by step how,
For just an element
XElement _root = new XElement("root");
_root.Save(fileName);
And the output will look like,
<?xml version="1.0" encoding="utf-8" ?>
<root />
Now if you want to add child to the root,
XElement _child = new XElement("child");
_root.Add(_child);
The generated XML would look like,
<root>
<child />
</root>
This work like DOM.
Now the .Add() method allows you pass values in form of object. So we can pass anything there,
XAttribute attr = new XAttribute("attrbt", 2008);
_root.Add(attr);
The XML view will be like,
<root attrbt="2008">
Now another interesting part is that the Add() method not only takes an object it also accepts array of objects. So you ideally do not have to call .Add() multiple times.
With the same output as before you can create you code,
_root.Add(_child, attr);
For more child you can simply keep on adding elements to the Add() method separated by comma.
XElement _child1 = new XElement("child1");
XElement _child2 = new XElement("child2");
XElement _child3 = new XElement("child3");
_root.Add(_child1, _child2, _child3, attr);
Now the output goes,
<child1 />
<child2 />
<child3 />
By using List<T> you can elegantly add elements to the root. Same output for this code,
List<XElement> childs = new List<XElement>
new XElement("child1"),
new XElement("child2"),
new XElement("child3")
_root.Add(childs, attr);
Now with all these options you can go ahead and use the constructor to add elements and attribute to your root.
So if I want to generate previous XML in one liner way, I could do this,
XElement _root = new XElement("root",
new List<XElement>
},
new XAttribute("attrbt", 2008));
//_root.Add(childs, attr);
Now I do not require Add() method at all.
Hope this gives you the idea about the basics of XElement and XAttribute. Thanks to Mike Taulty , I have learnt this from one of his finest demos.