How to query the SPView object

2019-04-14 00:43发布

问题:

I have a SPView object that contains a lot of SPListItem objects (there are many fields in the view).

I am only interested in one of these fields. Let's call it specialField

Given that view and specialField, I want to know if a value is contained in specialField.

Here is a way of doing what I want to do :

String specialField = "Special Field";
String specialValue = "value";
SPList list = SPContext.Current.Site.RootWeb.Lists["My List"];
SPView view = list.Views["My View"]; //This is the view I want to query

SPQuery query = new SPQuery();
query.Query = view.Query;
SPListItemCollection items = list.GetItems(query);
foreach(SPListItem item in items)
{
    var value = item[specialField];
    if(value != null) && (value.ToString() == specialValue)
    {
        //My value is found. This is what I was looking for.
        //break out of the loop or return
    }
}

//My value is not found.

However, iterating through each ListItem hardly seems optimal, especially as there might be hundreds of items. This query will be executed often, so I am looking for an efficient way to do this.

EDIT I will not always be working with the same view, so my solution cannot be hardcoded (it has to be generic enough that the list, view and specialField can be changed.

Would it better to cast it to an IEnumerable object? Say something like this :

list.GetItems(query).Cast<SPListItem>().Where(item => 
{
    return ((item[specialField] != null) && (item[specialField].ToString() == specialValue));
}).Count() > 0;

Would this be more efficient or am I heading in the wrong direction entirely?

回答1:

String specialField = "Special Field";
String specialValue = "value";
SPList list = SPContext.Current.Site.RootWeb.Lists["My List"];
SPView view = list.Views["My View"]; //This is the view I want to query

SPQuery query = new SPQuery();
string tmp = view.Query;
if(tmp.Contains("<Where>")) {
    //wrap the existing where clause in your needed clause (it should be an And i think)
    tmp = tmp.Insert(tmp.IndexOf("<Where>") + ("<Where>".Length), "<And><Eq><FieldRef Name='"+specialField+"'/><Value Type='Text'>"+specialValue+"</Value></Eq>");
    tmp = tmp.Insert(tmp.IndexOf("</Where>"), "</And>");
} else {
    //add a where clause if one doesnt exist
    tmp = "<Where><Eq><FieldRef Name='"+specialField+"'/><Value Type='Text'>"+specialValue+"</Value></Eq></Where>" + tmp;
}
query.Query = tmp;
SPListItemCollection items = list.GetItems(query);
if(item.Count > 0) {
    //My value is found. This is what I was looking for.
    //break out of the loop or return
} else {
    //My value is not found.
}


回答2:

You can execute queries in Caml. This is a good link for understanding queries in Caml and this is a link to software for building queries automatically.