Our data structure consists of two lists,
On-Hire Assets and Asset Notes, and a document library, Hire Contracts.
Document
libraries contain document-based content, and as a result, content
types that are used in a document library must be derived from the
built-in Document content type. When we created our Hire Contract
content type, we based it on the Document content type to meet this
requirement. By using a Document content type, we’re dictating that all
items must have an associated document, and this presents a problem for
LINQ.
LINQ to SharePoint is a data manipulation tool
designed to deal with the actual data that’s associated with an
individual item. The entity classes are created based on the fields
defined in the associated content types as opposed to the properties of
the object that manages the content. For example, most data items in
SharePoint are represented by the object model as an SPListItem object. The SPListItem has many properties, such as Title, Url, and UniqueId.
None of these properties is mapped to an entity object for use by LINQ
to SharePoint; instead, LINQ to SharePoint focuses only on the values
of the fields that are associated with the SPListItem. As a result, it’s impossible to manipulate any properties of an SPListItem
object (or any other object) using LINQ to SharePoint. In the case of a
Document-based item, we can’t create an object using LINQ, because
items stored in a document library must have an associated file. Since File is a property of the SPListItem object, we cannot set it via LINQ.
Since we can’t add documents to our document library
using LINQ, we can write some SharePoint code that makes use of the
object model to insert some sample data quickly.
Add Data Generation Buttons to LinqSampleApplication
In the LinqSampleApplication project, open Form1.cs.
From the toolbox, drag three button controls, a textbox, and a label
onto the design surface. The form designer should look like this:
Add Sample Contracts
Double-click the Add Sample Contracts button to add some code for the on-click event, and then add the following code:
private void button1_Click(object sender, EventArgs e)
{
//Add some sample data to the hire contracts document library
//disable the button to prevent concurrency problems
button1.Enabled = false;
using (SPSite mySite = new SPSite(SiteUrl.Text))
{
using (SPWeb myWeb = mySite.OpenWeb())
{
for (int x = 0; x < 3; x++)
{
//Since we're not interested in the document contents,
//create a simple text document
string test = x.ToString("This is test contract" +
" number 000");
byte[] content = System.Text.Encoding.UTF8.GetBytes(test);
//Get a reference to the Hire Contracts list
SPList HireContracts=myWeb.Lists["Hire Contracts"];
//Generate a sequential file name
string filename=x.ToString("SampleContract000.txt");
//Upload the file to the document library
SPFile newFile = HireContracts.RootFolder.Files.Add(filename,
content);
//Get a reference to the SPListItem that is automatically
//created when the document is uploaded
SPListItem item =newFile.Item;
//populate the mandatory fields with sample data
item["ContractId"] = x.ToString("CONT-000");
item["Contract Start Date"] = DateTime.Now.AddMonths(0-x);
item["Contract End Date"] = DateTime.Now.AddMonths(x+12);
//Persist the changes to the content database
item.SystemUpdate();
}
}
}
//change the text on the button so that we know the job's done
button1.Text += " - Done";
}
As you’ll see from the comments, this code simply
creates a few dummy Hire Contract documents in our document library.
Once the documents have been uploaded, the properties are set using
indexed properties on the SPListItem
object. You’ll notice that the field names and the name of the document
are not strongly typed. This is the problem we are addressing by using
LINQ.