1

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?

0

2 Answers 2

1

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);
                }
            }
        }
    }
2
  • i just get it that i can add hidden field with web id to news item and then use it in query.
    – Ievgen
    Dec 4, 2012 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 :) Dec 4, 2012 at 15:44
0

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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