Sharepoint - 获取两个SPListItemCollection之间的差异

时间:2014-03-28 14:19:56

标签: sharepoint sharepoint-2010 sharepoint-2013

我们要求用户无法访问的Sharepoint列表的项目必须仍然对前端的用户可见,并且选项为" Request Access"如有必要。为此,我们有一个Web服务,它首先从列表中提取所有项目,然后仅提取用户有权访问的项目。

// Get all the items in list
SPUser superUser = SPContext.Current.Web.AllUsers[@"SHAREPOINT\SYSTEM"];
SPUserToken superToken = superUser.UserToken;
SPList superList;
using (SPSite site = new SPSite(SPContext.Current.Web.Url, superToken))
{
    using (SPWeb elevatedWeb = site.OpenWeb())
    {
        superList = elevatedWeb.Lists.TryGetList(listname);
    }
}
SPListItemCollection superListItems = superList.GetItems(camlQuery);


// Get items in list accessible to current user
SPUser regularUser = SPContext.Current.Web.CurrentUser;
SPUserToken regularToken = regularUser.UserToken;
SPList regularList;
using (SPSite site = new SPSite(SPContext.Current.Web.Url, regularToken))
{
    using (SPWeb regularWeb = site.OpenWeb())
    {
        regularList = regularWeb.Lists.TryGetList(listname);
    }
}
SPListItemCollection regularListItems = regularList.GetItems(camlQuery);

接下来,需要计算两个list-item-collections之间的差异。如果可能的话,这应该足够简单:

// Now make a list of the items that the current user DOES NOT HAVE ACCESS TO
SPListItemCollection noAccessListItems;
foreach (SPListItem superListItem in superListItems)
{
    if(!regularListItems.Contains(superListItem)) // Fails here
    {
        noAccessListItems.Add(superListItem);
    }
}

唯一的问题是SPListItemCollection不支持.Contains()方法。

获取两个list-item-collection对象差异的最佳方法是什么?

2 个答案:

答案 0 :(得分:1)

您可以使用Cast来使用所有IEnumerable LINQ方法,例如Contains()。 使用try-catch这不是太漂亮的解决方案,imho。 你可以用一个简单的行来完成:

var noAccessListItems = regularListItems.Cast<SPListItem>().Where(x => !superListItems.Cast<SPListItem>().Select(y => y.ID).Contains(x.ID));

或者像这样:

var noAccessListItems = regularListItems.Cast<SPListItem>().Except(superListItems.Cast<SPListItem>());

但在这种情况下,您必须为SPListItem定义比较器。

<强> UPDATE1:

要定义比较器,您需要从IEqualityComparer继承的实现类,如下所示:

class SPListItemEqualityComparer : IEqualityComparer<SPListItem>
{
    public bool Equals(SPListItem i1, SPListItem i2)
    {
        return i1.ID == i2.ID;
    }

    public int GetHashCode(SPListItem item)
    {
        int hCode = item.ID;
        return hCode.GetHashCode();
    }
}

然后,您需要在Except方法中添加此类的实例作为第二个参数:

var noAccessListItems = superListItems.Except(regularListItems, new SPListItemEqualityComparer());

答案 1 :(得分:0)

好。搞定了。这有效:

// Now make a list of the items that the current user DOES NOT HAVE ACCESS TO
SPListItemCollection noAccessListItems;
foreach (SPListItem superListItem in superListItems)
{
    try
    {
        regularListItems.GetItemById(superListItem.ID);
    }
    catch(ArgumentException ae)
    {
        noAccessListItems.Add(superListItem);
    }
}