Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

Customer wants to see 10 news items from all webs on front page.

Also customer wants to specify some news that we should skip.

I am trying to do next thing:

var id =1; 

<Neq><FieldRef Name=\"ID\" /><Value Type=\"Counter\">" + id + "</Value></Neq>

But this query will skip all news from all webs with id = 1. I need to specify in query from which Web i should skip news:

For example:

!(id = 1 and webid=someId)

How to write such caml query?

share|improve this question

2 Answers 2

Evgeny,

Seems to be a possible duplicate of this questions:
Is it possible to filter SPSiteDataQuery results by site?

Answer from the post:

I don't think you can do this without some form of filtering post fetch. However, it isn't hard.

SPSiteDataQuery queries automatically include DataColumns in the DataTable for ListId and WebId, so you could then filter your DataTable by Web. I know it's not idea - 'query and filter', rather than just 'query' - but it should work.

The following queries for all documents with ID=1, and then filters to a particular Web. I guess your filter expression would be more complicated.

    using (SPSite site = new SPSite(url))
    {
        using (SPWeb web = site.OpenWeb())
        {
            SPSiteDataQuery q = new SPSiteDataQuery();
            q.Query = "<Where><Eq><FieldRef Name='ID' /><Value Type='Integer'>1</Value></Eq></Where>";
            q.Webs = "<Webs Scope='SiteCollection' />";
            q.Lists = "<Lists BaseType=\"1\" />";
            q.ViewFields = "<FieldRef Name='ID' /><FieldRef Name='FileLeafRef' />";

            DataTable table = web.GetSiteData(q);
            DataRow[] filteredRows = table.Select("WebId = '{282625A8-B13B-4DC0-B62E-D3255011FB5C}'");
            foreach (DataRow row in filteredRows)
            {
                foreach (DataColumn col in table.Columns)
                {
                    string colData = string.Empty;
                    if (row[col] != null)
                    {
                        colData = row[col].ToString();
                    }
                    Console.WriteLine("{0} : {1}", col.ColumnName, colData);
                }
            }
        }
    }
share|improve this answer
    
i just get it that i can add hidden field with web id to news item and then use it in query. –  Evgeny Dec 4 '12 at 15:13
1  
how will you do it, if you have figured out - please post the answer on the forum, it may be helpful for others :) –  Arsalan Adam Khatri Dec 4 '12 at 15:44
up vote 0 down vote accepted

We can add hidden fields for SITE ID and WEB ID to list.

Then in events reciever set those values for each new created item.

 private void UpdateHiddenFields(SPListItem item)
    {
        if (item.ContentType.Name == "MyContentType")
        {
            try
            {
                this.EventFiringEnabled = false;

                if (item != null)
                {
                    var isSiteChanged = UpdateGuidField(item, Constants.Lists.News.Fields.HiddenNewsSiteGUID, item.Web.Site.ID);
                    var isWebChanged = UpdateGuidField(item, Constants.Lists.News.Fields.HiddenNewsWebGUID, item.Web.ID);

                    if (isWebChanged || isSiteChanged)
                    {
                        item.SystemUpdate();
                    }
                }
            }
            catch (Exception ex)
            {
                LoggingService.WriteError(ex, "Cannot update hidden fields.");
            }
            finally
            {
                this.EventFiringEnabled = true;
            }
        }
    }

  private static bool UpdateGuidField(SPListItem item, string fieldName, Guid guidToSet)
        {
            if (item.Fields.ContainsField(fieldName))
            {
                var value = item[fieldName] as string;

                if (string.IsNullOrEmpty(value))
                {
                    item[fieldName] = guidToSet.ToString();
                    return true;
                }
                else
                {
                    var guid = value.ToGuid();

                    if (!guid.HasValue || guid.Value != guidToSet)
                    {
                        item[fieldName] = guidToSet.ToString();
                        return true;
                    }
                }
            }

            return false;
        }

Then we can use those fields in query.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.