Saturday, July 10, 2010

SharePoint LINQ Query Error

Issue

If you are using the new Microsoft.SharePoint.Linq API for SharePoint 2010 web parts you may run into the following problem. Here is some code:

TeamSiteDataContext context = new TeamSiteDataContext(SPContext.Current.Web.Url);

TeamSiteDataContext context = new TeamSiteDataContext(SPContext.Current.Web.Url);
EntityList<Task> tasks = context.GetList<Task>("Tasks");

DateTime? queryDate = new DateTime(2010, 7, 16);

var results = from tsk in tasks
where tsk.DueDate == queryDate
select tsk;

spGridView.DataSource = results;
spGridView.DataBind();

All I am doing is running a LINQ query for tasks. This code will give the following error:

One or more field types are not installed properly. Go to the list settings page to delete these fields.

Solution

While researching this, I found that if I got rid of the DueDate, the error would go away but that was not an acceptable solution. I did some research on and could not find anything on SharePoint 2010, as this was an issue you could have when writing SPQuery in older versions of SharePoint.

The ultimate solution was to change the second line to the following:

EntityList<TasksTask> tasks = context.GetList<TasksTask>("Tasks");

The reason is I used SPMetal to generate the proxy to SharePoint 2010. In the generated class there will be a Task and TasksTask classes. The Task maps to the generic content type while the TasksTask maps to the content type of the task list. When I used the class for the content type mapped to the list I was querying against, the error went away.

2 comments:

Cheers said...

I am facing the same issue with the due date, but i didn't understand your solution, please can you elaborate more. thank you

Jason Apergis said...

The solution is to NOT use the Task class but to use the TasksTask class.

Apparantly when you generate the proxy class using SPMetal it will generate a class for the Task content type. Then it will generate a class for each content type in the lists. It will name the class using the name of the list and the name of the content type. In my example I am using the Tasks list which uses the Task content type. So the class name is TasksTask. Once I used TasksTask everything started working.