IT tutorials
 
Technology
 

Sharepoint 2010 : Querying SharePoint Data (part 2) - Querying Using LINQ

10/5/2013 4:35:13 AM
- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019

2. Querying Using LINQ

The CAML join syntax is not the easiest to write or read. Let me complicate the picture a little bit further. What if you want it to not just query data but also to query the data and update the queried objects? While updating the queried objects, you want to take care of things such as concurrency. Not only that, most CAML queries are embedded in your code as strings. What if you want it to do compile time checking; in other words, strongly type code to represent your SharePoint site collection? All these things are not possible to do with pure CAML. But with SharePoint 2010, you have the ability of using LINQ to SharePoint, to address all these problems. Thus, SharePoint supports yet another way of interacting with its data, and that is LINQ to SharePoint.

For those of you who have worked with LINQ to SQL, LINQ to SharePoint is very similar. Just like LINQ to SQL, LINQ to SharePoint ships with a command-line utility called SPMetal that allows you to create a data context to interact with your SharePoint site. You can create such a data context on your sample data site using this command:

"%14%\bin\spmetal" /web:http://sp2010/sampledata /code:sampledata.cs

Note that 14 is an environment variable I have created that points me to the SharePoint root.

Executing the preceding command will create the data context in a file called "sampledata.cs". Go ahead and create a SharePoint console application and add this newly created file, and thus add your data context into your SharePoint console application. Also go ahead and add a reference to Microsoft.SharePoint.LINQ.dll. You can find Microsoft.SharePoint.LINQ.dll in the %14%\ISAPI folder.

With the data context ready, I'm going to show you three examples of using LINQ with SharePoint. I will demonstrate querying using a simple LINQ query, changing data using LINQ, and performing joins using LINQ.

First, let's see the example of a simple LINQ query. You can see the code for a simple LINQ query in Listing 4.

Example 4. A Simple LINQ Query
private static void SimpleLINQQuery()
{
Trace("Simple LINQ Query", true);
using (SampledataDataContext context = new SampledataDataContext(siteUrl))
{
var artistsMichael = from artist in context.Artists
where artist.Title.Contains("Michael")
select artist;

foreach (var artist in artistsMichael)
{
Trace(artist.Title);
}
}
}


As you can see from the listing, I create an instance of my SampleDataContext. I always do so in a using block because it'll automatically dispose the data context for me. With the data context ready, I can then execute a LINQ query as shown here:

var artistsMichael = from artist in context.Artists
where artist.Title.Contains("Michael")
select artist;

Executing the LINQ query then allows me to work with my queried objects in a very easy-to-read fashion, as shown here:

foreach (var artist in artistsMichael)
{
Trace(artist.Title);
}

Note that the trace methods are simply helper methods I have written in the associated code. This code is much easier to read and deal with than the CAML code. It is strongly typed, thus my errors are caught during compile time and not at runtime, and I can code more effectively using intellisense. The biggest disadvantage of LINQ, however, is that after your data context has been generated, changing the schema of the target site can potentially invalidate this generated data context.

Later on, I will show the best of both worlds, in which you have the resiliency of CAML -based code and the ease of writing of LINQ-based code.

Now let's say you have this data queried, how would you update the changes to this data back into SharePoint? When it comes to updating data, LINQ to SharePoint and LINQ to SQL, both work in a similar fashion.


The data context for both LINQ to SharePoint and LINQ to SQL builds upon that concept. There is, however, a method on the data context called RefreshData, which allows you to explicitly specify that you wish to overwrite you're in-memory objects with the latest representations from the original data source.

Excluding the case of calling RefreshData, usually all disconnected update models would appear to work as follows:

  1. Query data.

  2. Disconnect from the underlying data source

  3. Change some data.

  4. Submit the changes back to the data source.

Things get a little tricky at number 4 because while you were executing steps 2 and 3, someone else could have changed the data that you had queried. Thus in step 4 you need to perform concurrency checks before your data was written into the server. Similar to LINQ to SQL, step 4 is encapsulated in the SubmitChanges method of the DataContext. Also, there are various options you can specify to SubmitChanges to control the concurrency behavior. You can also use System.Transactions to control the transactional behavior on such updates.

But this is where LINQ to SharePoint and LINQ to SQL slightly bifurcate. Specifically, there are two things you need to be careful of when you call SubmitChanges in LINQ to SharePoint.

  • Try not to treat SharePoint like a high-volume transactional database. As mentioned previously, the SharePoint content database in SharePoint 2010 has undergone significant improvements from SharePoint 2007. This means that the database is less prone to issues such as locks and transaction isolation levels being elevated. However, it is probably still more prone to such issues than a highly optimized and customized SQL database.

  • Do not use transactions that span more than one content database. System.Transactions will work as long as you stick with a single content database because to prevent serializable isolation levels in transactions, SharePoint stores all its internal connection strings with "Enlist=False". This means databases are explicitly precluded from enlisting in distributed transactions a rather good idea. But it prevents cross-content database transactions from succeeding.

Now updating data using LINQ to SharePoint is extremely simple. You simply change the queried objects and then call the SubmitChanges method. THATS IT! No really, it is that simple. Thus in Listing 4, if you add the following two lines, you would change the data in the SharePoint list:

artist.Title = "Some new title";
dataContext.SubmitChanges() ;

Adding new items is slightly more involved but not difficult, either. You can see an example of adding a new artist in Listing 5.

Example 5. Adding a New Artist Using LINQ to SharePoint
private static void ChangeDataUsingLINQ()
{
Trace("Update Data Using LINQ", true);
using (SampledataDataContext context = new SampledataDataContext(siteUrl))
{
ArtistsItem duranduranArtist =
new ArtistsItem() { Country="USA", Title="Duran Duran" };
context.Artists.InsertOnSubmit(duranduranArtist);
context.SubmitChanges();
Trace("Item Added");
}
}


As you can see from Listing 5, I create a new instance of the ArtistsItem. I then use the InsertOnSubmit method to mark the newly created artists item to be persisted in the next SubmitChanges call. This causes my newly created artist to get added into the SharePoint list. Go ahead and execute the code shown in Listing 5 and verify that Duran Duran is actually added to the list.

Next, let's look at an example of performing joins using the LINQ to SharePoint. This is where LINQ to SharePoint truly shines! Go ahead and author a method as shown in Listing 6.

Example 6. Performing Joins Using LINQ to SharePoint
private static void JoinUsingLINQ()
{
Trace("LINQ Query with a Join", true);
using (SampledataDataContext context = new SampledataDataContext(siteUrl))
{
var songs = from song in context.Songs
where song.Artist.Title.Contains("Michael")
select song;

// context.Log = Console.Out;

foreach (var song in songs)
{
Trace(song.Title);
}
}
}


As you can see, performing a join using LINQ to SharePoint is a matter of simply dereferencing the appropriate object in the generated object model, as I am doing with song.Artist.Title. Because I was using look up columns, SPMetal.exe had enough information to create the object model to reflect the structure of my site, including all relationships defined by lookup columns. Executing the code shown in Listing 7 will show you an output as shown in Figure 5.

Figure 5. Results of a LINQ Join

As you can see, all songs that contain the word "Michael" in the artist name match in this query.

Earlier I mentioned that writing CAML queries by hand can be a little cumbersome. That problem is solved using LINQ to SharePoint. But LINQ to SharePoint introduces its own additional challenge of restricting the schema changes of the site after the DataContext has been generated. Is there a best of both worlds? Yes!

From Listing 7, uncomment the following line:

// context.Log = Console.Out;

Execute the code one more time. You should see an output shown in Figure 6.

Figure 6. Results of a LINQ Join with the Associated CAML Query

The LINQ query that LINQ to SharePoint was executing for you has been written out for you on the console. This query after cleanup is shown in Listing 8.

Example 8. Automatically Generated CAML Query by the Data Context
<View>
<Query>
<Where>
<And>
<BeginsWith>
<FieldRef Name="ContentTypeId" />
<Value Type="ContentTypeId">0x0100</Value>
</BeginsWith>


<Contains>
<FieldRef Name="ArtistTitle" />
<Value Type="Lookup">Michael</Value>
</Contains>
</And>
</Where>
</Query>
<ViewFields>
<FieldRef Name="Artist" LookupId="TRUE" />
<FieldRef Name="ID" />
<FieldRef Name="owshiddenversion" />
<FieldRef Name="FileDirRef" />
<FieldRef Name="Title"/>
</ViewFields>
<ProjectedFields>
<Field Name="ArtistTitle" Type="Lookup" List="Artist" ShowField="Title" />
</ProjectedFields>
<Joins>
<Join Type="LEFT" ListAlias="Artist">
<!—List Name: Artists—>
<Eq>
<FieldRef Name="Artist" RefType="ID" />
<FieldRef List="Artist" Name="ID" />
</Eq>
</Join>
</Joins>
<RowLimit Paged="TRUE">2147483647</RowLimit>
</View>


You're executing nothing but just a simple CAML query with joins. You could take the same query and get the same results if you wished. But then, of course, you will be restricted to doing updating using the regular SharePoint object model.

So you have an option here: you can either lean toward developer productivity and restrict schema changes, or you can have a very flexible system with resilient code, but have the developer work a bit harder, while borrowing such queries generated LINQ. As an architect, it is good to have choices!

 
Others
 
- Sharepoint 2010 : Querying SharePoint Data (part 1) - Querying Using CAML
- Windows Small Business Server 2011 : Creating a Data Collector Set (part 3) - Scheduling Data Collection
- Windows Small Business Server 2011 : Creating a Data Collector Set (part 2) - Constructing a Data Collector Set Manually
- Windows Small Business Server 2011 : Creating a Data Collector Set (part 1) - Building a Data Collector Set from a Template
- Windows Small Business Server 2011 : Using Reliability Monitor, Managing Collected Data
- Windows 8 : BitLocker Drive Encryption: The Essentials (part 3) - Deploying BitLocker Drive Encryption
- Windows 8 : BitLocker Drive Encryption: The Essentials (part 2) - Hardware Encryption, Secure Boot, and Network Unlock
- Windows 8 : BitLocker Drive Encryption: The Essentials (part 1) - Understanding BitLocker Drive Encryption
- System Center Configuration Manager 2007 : Patch Management - Troubleshooting Software Updates
- System Center Configuration Manager 2007 : Patch Management - Using NAP to Protect Your Network (part 2) - System Health , Client Compliance
 
 
Top 10
 
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
Technology FAQ
- Is possible to just to use a wireless router to extend wireless access to wireless access points?
- Ruby - Insert Struct to MySql
- how to find my Symantec pcAnywhere serial number
- About direct X / Open GL issue
- How to determine eclipse version?
- What SAN cert Exchange 2010 for UM, OA?
- How do I populate a SQL Express table from Excel file?
- code for express check out with Paypal.
- Problem with Templated User Control
- ShellExecute SW_HIDE
programming4us programming4us