views:

2913

answers:

2

Following on from suggestions, I am trying to use List.GetItems(Query) to retrieve my initial data subset rather than the entire list contents via List.Items. However, whereas List.Items.Cast() results in a usable IEnumerable for Linq, List.GetItems(Query).Cast() does not.

Working Code:

IEnumerable<SPListItem> results = SPContext.Current.Web.Lists[ListName].Items.Cast<SPListItem>().Where(item => item["Date"] != null).Where(item => DateTime.Parse(item["Date"].ToString()) >= StartDate).Where(item => DateTime.Parse(item["Date"].ToString()) <= EndDate);
MessageLine = results.Count().ToString();

Non-working Code:

string SPStartDate = SPUtility.CreateISO8601DateTimeFromSystemDateTime(this.StartDate);
string SPEndDate =   SPUtility.CreateISO8601DateTimeFromSystemDateTime(this.EndDate);

SPQuery MyQuery = new SPQuery();
MyQuery.Query = "<Where><And><And><Geq><FieldRef Name='Date'/><Value Type='DateTime'>" + SPStartDate + "</Value></Geq><Leq><FieldRef Name='Date'/><Value Type='DateTime'>" + SPEndDate + "</Value></Leq></And></Where>";

IEnumerable<SPListItem> results = SPContext.Current.Web.Lists[ListName].GetItems(MyQuery).Cast<SPListItem>();

MessageLine = results.Count().ToString();

The List.GetItems(Query).Cast() method produces the following Exception on the .Count() line:

Microsoft.SharePoint.SPException: Cannot complete this action. Please try again. ---> System.Runtime.InteropServices.COMException (0x80004005): Cannot complete this action. Please try again. at Microsoft.SharePoint.Library.SPRequestInternalClass.GetListItemDataWithCallback(String bstrUrl, String bstrListName, String bstrViewName, String bstrViewXml, SAFEARRAYFLAGS fSafeArrayFlags, ISP2DSafeArrayWriter pSACallback, ISPDataCallback pPagingCallback, ISPDataCallback pSchemaCallback) at Microsoft.SharePoint.Library.SPRequest.GetListItemDataWithCallback(String bstrUrl, String bstrListName, String bstrViewName, String bstrViewXml, SAFEARRAYFLAGS fSafeArrayFlags, ISP2DSafeArrayWriter pSACallback, ISPDataCallback pPagingCallback, ISPDataCallback pSchemaCallback) --- End of inner exception stack trace --- at Microsoft.SharePoint.Library.SPRequest.GetListItemDataWithCallback(String bstrUrl, String bstrListName, String bstrViewName, String bstrViewXml, SAFEARRAYFLAGS fSafeArrayFlags, ISP2DSafeArrayWriter pSACallback, ISPDataCallback pPagingCallback, ISPDataCallback pSchemaCallback) at Microsoft.SharePoint.SPListItemCollection.EnsureListItemsData() at Microsoft.SharePoint.SPListItemCollection.Undirty() at Microsoft.SharePoint.SPBaseCollection.System.Collections.IEnumerable.GetEnumerator() at System.Linq.Enumerable.d__aa1.MoveNext() at System.Linq.Enumerable.Count[TSource](IEnumerable1 source) at Test.GetTransactionsInPeriod() at Test.CreateChildControls()

Can anyone suggest anything?

+5  A: 

From the error message it looks like the CAML Query is wrong. You may want to run it through something like U2U's CAML Query Builder to double check. The error message is thrown by SharePoint before the requested casts. Glancing over it, I think you have an extra <And> at the beginning (<Where><And><And>)

By the way: Don't use SPWeb.Lists[Name]. This will load every list in the SPWeb (including Metadata), which is rather resource intensive. One of the SPWeb.GetList or SPWeb.Lists.GetList methods is better.

Michael Stum
Well, wouldn't you know it - it was the CAML Query. How did you come to that conclusion from that error message, I wouldn't have ever have put that together? Thankyou for the suggestion of the query builder, it looks like its a very useful tool. Also, thanks for the pointer on the SPWeb.Lists[] - if it applies to List.Items then of course it applies to Web.Lists!
Moo
@Moo: CAML queries are often difficult to get right. U2U CAML Query Builder that Michael suggests will save you heaps of time.
Alex Angas
Experience :-) Two things: "Cannot complete this action." is the typical Sharepoint message for "Something is wrong with the CAML" - the other typical message would have been "One or more field types are not installed correctly", which is also unhelpful but clearly SharePoint. Then: LINQ is a .net Framework Technology, so it should have thrown a meaningful error message, so it had to be SharePoint. Generally: Meaningful Error = .net Framework related, Useless Error message = SharePoint related.
Michael Stum
Also the fact that it's an SPException means it has to come from SharePoint, so it has to come from one of the "inner" calls, which only leaves two options: The call to Lists[ListName] or the call to GetItems. The Cast wouldn't throw a SPException, and neither would results.Count or results.Count.ToString()
Michael Stum
A: 

thanks Michael.. your answer really helped me regain my hair otherwise i'd have gone bald in frustration.. there was trouble my CAML query as well :) Thanks again

-Hardik

Hardik