Repository pattern with LINQ to SharePoint DSL Extension (part 2)
In the first part of this tutorial, I explained the basics about the repository pattern implementation in the LINQ to SharePoint DSL Extension for Visual Studio 2010. In this previous post, I explained how to create a new Repository pattern thanks to a new Visual Studio item. This item uses an existing LINQ to SharePoint data model (l2sp file) to generate automatically a repository pattern implementation. The classes diagram is also available in this previous post.
In this second part, I will explain how to use the object model to call the repository layer in your code with a sample model.
This sample model (the l2sp file) provides the following SharePoint data model:
My data model is called "AdventureWorks" and I added a new "LINQ to SharePoint data model repository" in my Visual Studio project. All the following samples show how to use the generated repository for this model.
How to use the repositories factory
LINQ to SharePoint DSL Extension repository generator generates a factory object context. This factory is an object conception to manipulate operations on the LINQ data context without hard coded references to the concrete type.
The factory is obtained from a static method. You can call this method when you need to get a new factory instance.
For example:
using (IAdventureWorksFactory factory = AdventureWorksFactory.GetNewInstance(SPContext.Current.Web.Url))
{
//Get a category by id
Category category = factory.Categories.GetById(2);
category.Title = "Hello";
factory.SubmitChanges();
}
The factory object provides all the properties and methods to manage the entities repositories. The definition of the factory is very similar to the LINQ to SharePoint DataContext class:
https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.linq.datacontext.aspx
With the repository implementation, you don’t have a hard coded reference to this data context. The factory object returned by the GetNewInstance method must simply implement the IAdventureWorksFactory interface. With this pattern, you can change tomorrow the complete design of data access layer, by using other data access classes implementation. This method is useful when you want to test your business layer with test units based on a non-SharePoint data context for example.
The factory instance provides the following things:
- Methods to manage the data context (similar as DataContext class), for example SubmitChanges, etc.
- Properties to get repository implementations. For each list in the schema, you have a property to get it. For example: ICategoriesRepository categories = factory.Categories; The list of repository implementations is similar to the property EntityList<Category> of the DataContext class.
The generated repository classes and interfaces contain:
- The All property to get the LINQ requestable IQueryable<Category> object
- The same methods of the EntityList class (like DeleteOnSubmit, etc.)
- A set of custom generated helpers methods to build LINQ queries on your entities (see more information about helpers in the “Use the helper methods” chapter.
Create, Delete and Update methods
When you’re using the repository pattern classes, the “create”, “delete” and “update” operations are similar as the direct LINQ to SharePoint methods.
Create method sample:
//Get the instance of the repository factory
using (IAdventureWorksFactory factory = AdventureWorksFactory.GetNewInstance(SPContext.Current.Web.Url))
{
//Get a category by id
Category category = new Category();
//or:
//Category category = factory.Categories.CreateNew();
category.Title = "New category";
factory.Categories.InsertOnSubmit(category);
factory.SubmitChanges();
}
Update method sample:
using (IAdventureWorksFactory factory = AdventureWorksFactory.GetNewInstance(SPContext.Current.Web.Url))
{
//Get a category by id
Category category = factory.Categories.GetById(2);
category.Title = "Updated category";
factory.SubmitChanges();
}
Delete method sample:
//Get the instance of the repository factory
using (IAdventureWorksFactory factory = AdventureWorksFactory.GetNewInstance(SPContext.Current.Web.Url))
{
//Get a category by id
Category category = factory.Categories.GetById(2);
factory.Categories.DeleteOnSubmit(category);
factory.SubmitChanges();
}
Use the All property to build LINQ queries
When you’re using a repository object, this object is not directly request able. But each repository instance has an “All” property which implements IQueryable<T>. For example, the ICategoryRepository object instance has a property All of type IQueryable<T>. You can build all the LINQ queries that you want thanks to this object. You can use all the Lambda expression that you want with this property.
For example:
using (IAdventureWorksFactory factory = AdventureWorksFactory.GetNewInstance(SPContext.Current.Web.Url))
{
//Get categories queryable object
IQueryable<Category> all = factory.Categories.All;
//LINQ query
IQueryable<Category> filteredCategories =
from t in all
where t.Version > 2
orderby t.Version
descending select t).Take(5);
//Browse results
foreach (Category category in filteredCategories)
{
Console.WriteLine(category.Title);
}
}
Use the helper methods
The LINQ to SharePoint DSL Extension will generate a lot of pre-coded LINQ procedures to manage queries on entities. The principle of this code is to provide specialized methods for all the properties of your entities. These methods and prototypes are useful for the developers to quickly develop code without high skills with Lambda LINQ expressions.
For more information about these helpers methods, please read the first part of this tutorial.
Helpers method sample:
using (IAdventureWorksFactory factory = AdventureWorksFactory.GetNewInstance(SPContext.Current.Web.Url))
{
//First get all the models where the title contains the string "shoes"
IEnumerable<Model> models = factory.Models.GetWhereTitleContains("Shoes");
//Filter models where the version is greater than 10, ascending by version and limit to 100 elements
models = Factory.Models.GetWhereVersionIsGreaterThan(models, 10, true, 100);
// Databinds the results data in a data list ASP.Net web control
if (models == null || models.Count() == 0)
this.DataListProducts.Visible = false;
else
{
this.DataListProducts.DataSource = models;
this.DataListProducts.DataBind();
}
}
In this previous sample, you can notice than you can combine helper methods thanks to the prototypes with the first IQueryable<T> source argument.
To conclude, you can see that when you're using the repository layer code, your code looks like a direct LINQ to SharePoint call. But with this implementation, your code only uses only interfaces of the factory and the repositories, without hard coded references to the LINQ to SharePoint API. This feature is useful to a lot of things, like for example to implement a unit tests layer. More over, you can use all the generated helpers methods to make queries easily on your model.
In the next part of this tutorial, I will show you how to extend this repository layer and all the advanced settings about it.