If you cannot pull the entire SQL table into an external list, then you cannot query this dataset as you could in a SharePoint list.
However, I can offer a solution that we used for scenarios that were almost identical to this, which worked very well for us. In our scenario, we query the Oracle database, which forever returns large data sets.
The approach we used was to use the Factory pattern to determine how the data source should be queried (SharePoint list, external database, etc.).
The following are examples, but they illustrate the concept well.
So, start with an interface that determines how the data set will be set and which fields will be returned:
public interface IQueryData { string ListToQuery { get; set; } List<MyResultObject> ExecuteQuery(); }
You will have a custom object representing a single record returned by the request
public class MyResultObject { public string FileRef { get; } public string Title { get; set; }
Then you will have a data provider that implements this interface for the SQL data source
public class SqlDataProvider : IQueryData { public string ListToQuery { get { return "BigSqlTable"; } } public List<MyResultObject> ExecuteQuery() {
You will also have a data provider that implements an interface for a SharePoint data source.
public class SharePointDataProvider : IQueryData { public string ListToQuery { get { return "MySharePointList"; } } public List<MyResultObject> ExecuteQuery() {
In this implementation, you encapsulated the logic and details of the request in your respective data providers.
Now you will have a Factory, which builds the corresponding data provider (based on the specified ListToQuery parameter):
public static class QueryDataProviderFactory { public static IQueryData Build(string listToQuery) { switch(listToQuery) { case "BigSqlTable": return new SqlDataProvider(); break; case "MySharePointList": return new SharePointDataProvider(); break;
Finally, you should use your Factory to initiate your request, passing in the name of the data source you want to request:
public List<MyResultObject> RunQuery() { return QueryDataProviderFactory.Build("BigSqlTable").ExecuteQuery(); }
This template keeps your external implementation encapsulated in its own data provider and abstracts the details of the request from the consumer. All the consumer needs to do is specify the name of the list they want to request, and Factory decides which implementation to initiate.
You can even make your IQueryData interface an implementation of generics for further extensibility:
public interface IQueryData<T> { string ListToQuery { get; set; } List<T> ExecuteQuery(); }
This will open the door for the consumer to also indicate the type of object they would expect to return.
There are many more members in our query data interface that add even more extensibility points to our query providers, but I thought this example illustrates the point in a concise and easy to understand form.
I just wanted to offer this proposal, because it looks like the same scenario that we encountered a year ago, and this strategy works very well for us.