文章目錄
LINQ to SharePoint是2010版的SharePoint的一個很好的新特性,用於對SharePoint伺服器發起查詢。不同於經典CAML的查詢,它是通過一個強型別的實體模型和LINQ查詢文法來查詢列表資料。
SPMetal命令
正如上一篇文章中提到的那樣,使用LINQ to SharePoint的第一步就是運行SPMetal工具來為已有的SharePoint網站建立實體模型。此工具位於14\ BIN。這裡有一個如何使用它的樣本:
SPMetal /web:http://我們的SharePoint網站:連接埠 /code:SiteEntities.cs
這個命令將在在14\ BIN下建立一個名為 Model.cs 的C#代碼檔案,其中包含了實體模型。將這個檔案添加到我們的項目後,我們就可以使用LINQ to SharePoint來執行查詢了。例如,可以使用如下的伺服器端代碼,輸出“Manager”列表中標題長度至少為3個字元長所有清單項目:
using (SiteEntitiesDataContext ctx = new SiteEntitiesDataContext("http://moss.contoso.com/sites/Lab01")){ StringBuilder output = new StringBuilder(); foreach (Manager項目 manager in ctx.Manager.Where(x => x.標題.Length >= 3)) { output.AppendLine(manager.名稱); } Console.WriteLine(output.ToString());}
丟失的欄
預設情況下,建立者,建立時間,修改者,修改時間這些欄不會被SPMetal自動建立。然而,該架構提供了對LINQ to SharePoint提供者的擴充能力,可以擴充其中的對象——關係映射系統。換句話說,一旦我們告訴了LINQ to SharePoint如何從內容資料庫中檢索和更新這些欄,那麼以後就可以很容易地使用這些欄了。
下面我們就動手擴充模型的基礎實體類(“項目”類),建立一個C#代碼檔案(這裡命名為“ModelExtensions.cs”):
using System;using System.Collections.Generic;using System.Linq;using System.Text;using Microsoft.SharePoint.Linq;using Microsoft.SharePoint;public partial class 項目 : ICustomMapping{ [CustomMapping(Columns = new String[] { "Modified", "Created", "Editor", "Author" })] public void MapFrom(object listItem) { SPListItem item = (SPListItem)listItem; this.Modified = (DateTime)item["Modified"]; this.Created = (DateTime)item["Created"]; this.CreatedBy = (string)item["Author"]; this.ModifiedBy = (string)item["Editor"]; } public void MapTo(object listItem) { SPListItem item = (SPListItem)listItem; item["Modified"] = this.Modified; item["Created"] = this.Created; item["Author"] = this.CreatedBy; item["Editor"] = this.ModifiedBy; } public void Resolve(RefreshMode mode, object originalListItem, object databaseObject) { SPListItem originalItem = (SPListItem)originalListItem; SPListItem databaseItem = (SPListItem)databaseObject; DateTime originalModifiedValue = (DateTime)originalItem["Modified"]; DateTime dbModifiedValue = (DateTime)databaseItem["Modified"]; DateTime originalCreatedValue = (DateTime)originalItem["Created"]; DateTime dbCreatedValue = (DateTime)databaseItem["Created"]; string originalCreatedByValue = (string)originalItem["Author"]; string dbCreatedByValue = (string)databaseItem["Author"]; string originalModifiedByValue = (string)originalItem["Editor"]; string dbModifiedByValue = (string)databaseItem["Editor"]; if (mode == RefreshMode.OverwriteCurrentValues) { this.Modified = dbModifiedValue; this.Created = dbCreatedValue; this.CreatedBy = dbCreatedByValue; this.ModifiedBy = dbModifiedByValue; } else if (mode == RefreshMode.KeepCurrentValues) { databaseItem["Modified"] = this.Modified; databaseItem["Created"] = this.Created; databaseItem["Author"] = this.CreatedBy; databaseItem["Editor"] = this.ModifiedBy; } else if (mode == RefreshMode.KeepChanges) { if (this.Modified != originalModifiedValue) { databaseItem["Modified"] = this.Modified; } else if (this.Modified == originalModifiedValue && this.Modified != dbModifiedValue) { this.Modified = dbModifiedValue; } if (this.Created != originalCreatedValue) { databaseItem["Created"] = this.Created; } else if (this.Created == originalCreatedValue && this.Created != dbCreatedValue) { this.Created = dbCreatedValue; } if (this.CreatedBy != originalCreatedByValue) { databaseItem["Author"] = this.CreatedBy; } else if (this.CreatedBy == originalCreatedByValue && this.CreatedBy != dbCreatedByValue) { this.CreatedBy = dbCreatedByValue; } if (this.ModifiedBy != originalModifiedByValue) { databaseItem["Editor"] = this.ModifiedBy; } else if (this.ModifiedBy == originalModifiedByValue && this.ModifiedBy != dbModifiedByValue) { this.ModifiedBy = dbModifiedByValue; } } } public DateTime Modified { get; set; } public DateTime Created { get; set; } public string CreatedBy { get; set; } public string ModifiedBy { get; set; }}
更多關於ICustomMapping介面的介紹,可以查看這些MSDN文章:ICustomMapping成員和RefreshMode枚舉。
將這個檔案添加到我們的項目後,在我們進行查詢時可以使用建立者,建立時間,修改者,修改時間了:
StringBuilder output = new StringBuilder();using (SiteEntitiesDataContext model = new SiteEntitiesDataContext("http://moss.contoso.com/sites/Lab01")){ string dateStr = ("2012/8/6 16:22").ToString(CultureInfo.InvariantCulture); DateTime convertedDate = DateTime.SpecifyKind(DateTime.Parse(dateStr), DateTimeKind.Utc); foreach (Manager項目 manager in model.Manager.Where(x => x.Created > convertedDate)) { output.AppendLine(manager.標題 + " " + manager.名稱); }}Console.WriteLine(output.ToString());
還是用原來的Manager列表,在當前視圖中增加顯示“建立時間”一欄:
以上的代碼查詢所有建立時間晚於16:22的清單項目。結果如下:
需要注意的是,作者和修改者這兩個欄是User類型的。直接輸出這些字串的話可能會含有很多你不需要的資訊。解析這鐘字串的一個簡單方法是建立一個SPFieldUserValue,用當前的SPWeb和這個字串作為參數。然後,我們可以從SPFieldUserValue.User中提取出實際需要的SPUser資訊。
比如:
using(SPSite site=new SPSite("http://moss.contoso.com/sites/Lab01")){ using (SPWeb web = site.OpenWeb()) { using (SiteEntitiesDataContext ctx = new SiteEntitiesDataContext("http://moss.contoso.com/sites/Lab01")) { var result = ctx.Manager.Where(m => m.國家 == 國家.USA); foreach (Manager項目 manager in result) { SPFieldUserValue t = new SPFieldUserValue(web, manager.CreatedBy); Console.WriteLine(manager.標題 + " " + manager.名稱 + " - " + t.User.Name + " - " + manager.Modified.ToShortDateString()); } } }}
輸出結果為:
希望此代碼對你有協助,Enjoy SharePoint!
參考資料
LINQ To SharePoint: Working with Created, CreatedBy, Modified and ModifiedBy