• Linq to Sharepoint(转)


    http://weblogs.asp.net/uruit/archive/2011/05/05/linq-to-sharepoint-working-with-created-createdby-modified-and-modifiedby.aspx

    http://www.cnblogs.com/Sunmoonfire/archive/2012/08/07/2625955.html

    介绍

    在本文中,我们将介绍以下高级开发领域中的内容:
    •LINQ to SharePoint
    •SPMetal
    LINQ to SharePoint 是SharePoint 2010的一项新特性。 LINQ 本身是 Language Integrated Query 的意思,它是 .NET的一个组成部分。 LINQ的设计目标是使用相同的类型化查询语法来支持不同类型的数据源。到目前为止,它可以支持Objects, Datasets, SQL, Entities, XML等。

    为什么我们需要 LINQ?

    从前我们针对 List 的编程都是使用相应的栏名来访问。有了LINQ 之后,我们就使用类型化的方式访问列表了。换句话说,使用类似访问数据库的方式去访问列表项。
    就像下面这样:

    var result = from c in Citizen where c.Name == “John” select c;

    什么是SPMetal?

    我们创建了一个包含自定义栏的自定义列表后,还需要创建一个实体模型(Entity Model)与之对应,这样才能用LINQ来访问它。 SPMetal.exe 就是一个帮助我们生成 Model 类的工具。尽管我们可以手工创建Model 类,但毕竟这属于枯燥单调的工作,并且很容易出错。 所以用SPMetal 才是生成model 类的王道。

    活动

    本文将包含以下活动:
    1.    Manager 列表创建
    2.    实体创建
    3.    使用LINQ读取
    4.    插入实体
    5.    更新实体
    6.    删除实体

    开始 LINQ 和SPMetal 的体验之旅

    作为实验对象,我们创建了一个自定义列表,名为Manager. 添加如下的自定义栏和数据:

    生成实体模型

    现在,我们就可以为以上列表生成实体模型。使用这个文件夹下的 SPMetal.exe来生成模型类:

    C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\BIN
    打开命令行,进到该文件夹:

    运行如下命令:

    SPMetal.exe /web:http://你的站点 /code:SiteEntities.cs

     过一会儿我们就会生成出一个新文件。打开SiteEntities 文件,我们就可以看到其中包含的Manager 类。

    创建应用程序

    新建一个SharePoint > 2010 > 控制台应用程序 (目标框架 .NET 3.5 framework) 并将 SiteEntities.cs 文件添加到该项目。

    添加如下程序集引用:

    我们可以尝试以下操作: 通过LINQ to SharePoint读取,插入,更新,删除。

    读取项

    我们先试一下查询country 为USA 的managers :

    复制代码
    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.名称);
               }
    }
    复制代码

    注: 我们可以使用 LINQ 或 Lambda 表达式来进行查询。上面的例子中我们用的是Lambda。
    运行该应用程序,我们可以看到如下的结果。

    插入项

    如果要在Manager 列表中插入数据,可以使用如下代码:

    using (SiteEntitiesDataContext ctx = new SiteEntitiesDataContext("http://moss.contoso.com/sites/Lab01"))
    {
             Manager项目 manager = new Manager项目();
             manager.名称 = "新的经理";
             manager.地址 = "新的地址";
             manager.国家 = 国家.China;
             ctx.Manager.InsertOnSubmit(manager);
             ctx.SubmitChanges();
    }

     执行以上程序后,打开SharePoint 中的Manager 列表,可以看到如下结果:

    更新项

    如果要更新SharePoint 中的列表项,可以使用如下代码:

    using (SiteEntitiesDataContext ctx = new SiteEntitiesDataContext("http://moss.contoso.com/sites/Lab01"))
     {
            Manager项目 manager = ctx.Manager.Where(m => string.IsNullOrEmpty(m.标题)).FirstOrDefault();
             if (manager != null)
             {
                   manager.标题 = "新的标题";
             }
              ctx.SubmitChanges();
    }

     我们可以在SharePoint 上看到更新后的实体:

    删除项

    如果要删除SharePoint 中的列表项,可以使用如下代码:

    using (SiteEntitiesDataContext ctx = new SiteEntitiesDataContext("http://moss.contoso.com/sites/Lab01"))
    {
            Manager项目 manager = ctx.Manager.Where(m => m.标题.Length>3).FirstOrDefault();
            if (manager != null)
            {
                 ctx.Manager.DeleteOnSubmit(manager);
             }
             ctx.SubmitChanges();
    }

     我们可以看到在SharePoint 中的该项已被删除:

    以上就是如何通过LINQ to SharePoint 实现增删改查。希望大家都可以掌握。

    总结

    本文中我们使用了 LINQ 和SPMetal 工具。这些都是在实际的编程场景中经常使用的工具。

    参考资料

    http://msdn.microsoft.com/en-us/library/ee535491.aspx
    http://msdn.microsoft.com/en-us/library/ee538255.aspx
    SharePoint 2010 – LINQ and SPMetal

    如何使用创建时间,修改者等系统信息?

    INQ 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#代码文件(这里命名为“Item.cs更多关于ICustomMapping接口的介绍,可以查看这些MSDN文章:ICustomMapping成员RefreshMode枚举

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.SharePoint.Linq;
    using Microsoft.SharePoint;
    
    namespace MossTest
    {
        public partial class Item : 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; }
        }
    }


    将这个文件添加到我们的项目后,在我们进行查询时可以使用创建者,创建时间,修改者,修改时间了:

    复制代码
    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与权限提升

    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;
    }

    }
    }
    });

  • 相关阅读:
    ASP.NET程序中常用的三十三种代码
    .NET面试题之1
    Assembly ‘X’ could not be uninstalled because it is required by another application
    Globalization and Localization
    SQL 2005 Reporting Services:物理分页和逻辑分页 SSRS 2008 report export to PDF Cannot get size to work
    GAC 学习
    Repeating Tablix Headers In SSRS 2008
    How do work with NULL in TSQL
    Visual C++ Native and .NET Interoperability
    C# WinForm开发系列 Reporting Services
  • 原文地址:https://www.cnblogs.com/ceci/p/2879835.html
Copyright © 2020-2023  润新知