using (SiteEntitiesDataContext ctx = new SiteEntitiesDataContext("http://moss.contoso.com/sites/Lab01"))
{
var result = ctx.Manager.Where(m => m.国家 == 国家.USA);
foreach (Manager项目 manager in result)
{
Console.WriteLine(manager.名称);
}
}
这个命令将在在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#代码文件(这里命名为“Item.cs更多关于ICustomMapping接口的介绍,可以查看这些MSDN文章:ICustomMapping成员和RefreshMode枚举。
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与权限提升
SharePoint 2010支持Linq to SharePoint,让程序员可以使用Linq语法直接访问SharePoint 2010网站中的数据。但是在默认情况下,Linq to SharePoint不支持权限提升,也就是说,如果在代码中尝试通过SPSecurity.RunWithElevatedPrivileges()方 法来提升执行权限,你可能会发现,代码并不会如你所愿的以系统帐户的身份,访问SharePoint网站的数据。
下面是一段典型的权限提升的代码,在匿名委托方法中,首先构造了新的SPSite和SPWeb对象,然后使用Linq to SharePoint查询了一个列表中所有列表项的标题。虽然看起来Linq to SharePoint好像会被提升它执行的权限,但实际情况并非如此。在下面的代码中,中间的Linq to SharePoint代码并不会受到外面调用SPSecurity.RunWithElevatedPrivileges()方法的影响。
private IEnumerable<String> GetAllHardwareNames()
{
var currentWebUrl = SPContext.Current.Web.Url;
List<String> result = null;
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (var site = new SPSite(currentWebUrl))
{
using (var web = site.OpenWeb())
{
using (var ctx = new ContosoDataContext(currentWebUrl))
{
var names = from h in ctx.硬件资产跟踪
select h.标题;
result = names.ToList();
}
}
}
});
return result;
}
如果希望Linq to SharePoint代码能够提升它的执行权限,在使用Linq to SharePoint之前,需要做一个比较trick的事情,那就是将当前HttpContext对象设置为null。下面的代码中,使用粗体标识了这些特殊的代码。
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (var site = new SPSite(currentWebUrl))
{
using (var web = site.OpenWeb())
{ var httpContext = HttpContext.Current;
HttpContext.Current = null;
using (var ctx = new ContosoDataContext(currentWebUrl))
{
var names = from h in ctx.硬件资产跟踪
select h.标题;
result = names.ToList();
} HttpContext.Current = httpContext;
}
}
});
只所以要使用这个技巧,是因为在Linq to SharePoint的实现中,使用了一个名为 Microsoft.SharePoint.Linq.Provider.SPServerDataConnection的类,来真正连接到 SharePoint网站。在这个类的构造函数中,有类似这样的代码:
if (SPContext.Current != null)
{
this.defaultSite = SPContext.Current.Site;
this.defaultWeb = (SPContext.Current.Web.Url == url) ? SPContext.Current.Web : this.defaultSite.OpenWeb(new Uri(url).PathAndQuery);
}
else
{
this.defaultSite = new SPSite(url);
this.defaultWeb = this.defaultSite.OpenWeb(new Uri(url).PathAndQuery);
}
为了提高性能,它会优先重用SPContext对象中所缓存的SPWeb和SPSite对象。这个行为虽然可以提高代码的运行效率,但是却会导致权限提升的失效,因为提升了权限的代码必须使用一个新构造的SPSite和SPWeb对象。
实际使用:
int currentUserID = Web.CurrentUser.ID;
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (var site = new SPSite(Web.Url))
{
using (var web = site.OpenWeb())
{ //linq to sharepoint runwith required var httpContext = HttpContext.Current;
try
{ //linq to sharepoint runwith required HttpContext.Current = null;
using (ProjectManagementWebDataContext dc = new ProjectManagementWebDataContext(web.Url))
{
DeliveryItem delivery = new DeliveryItem();
delivery.Title = tbPart.Text;
delivery.PMId = currentUserID;
dc.Delivery.InsertOnSubmit(delivery);
dc.SubmitChanges();
//remaining code goes here...
}
}
catch (Exception ex)
{
JavaScript.Alert(string.Format("Error: {0}", ex.Message), this.Page);
return;
}
finally
{ //linq to sharepoint runwith required HttpContext.Current = httpContext;
}
}
}
});