Methods and properties such as SPWeb.GetSubWebsForCurrentUser, SPSite.AllWebs and SPWeb.Webs, all return an object of the SPWebCollection class and the WebsInfo property can be used as a wrapper on some basic information about each web.
The properties available in the WebInfo class are:
- Configuration
- CustomMasterUrl
- Description
- Id
- Language
- LastItemModifiedDate
- MasterUrl .
- ServerRelativeUrl
- Title
- UIVersion
- UIVersionConfigurationEnabled
- WebTemplateId
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
SPSite site = SPContext.Current.Site; | |
SPWebCollection subWebs = site.AllWebs; | |
foreach (SPWebInfo webInfo in subWebs.WebsInfo) | |
{ | |
//Code used only for testing. | |
var result = webInfo.Title + | |
webInfo.ServerRelativeUrl + | |
webInfo.Description + | |
webInfo.Id + | |
webInfo.Language + | |
webInfo.LastItemModifiedDate + | |
webInfo.WebTemplateId + | |
webInfo.Configuration + | |
webInfo.UIVersionConfigurationEnabled + | |
webInfo.UIVersion + | |
webInfo.MasterUrl + | |
webInfo.CustomMasterUrl; | |
} |
So only 1 database query was made with the procedure proc_ListAllWebsOfSite. After opening this procedure in the Content Database, it contained this piece of code:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
BEGIN | |
SELECT | |
A.FullUrl, | |
A.Id, | |
ISNULL(B.FullUrl, A.FullUrl), | |
A.Language, | |
ISNULL(A.Title, ''), | |
A.UIVersion, | |
A.Flags, | |
A.WebTemplate, | |
A.ProvisionConfig, | |
A.MasterUrl, | |
A.CustomMasterUrl | |
FROM | |
TVF_Webs_NoLock_SiteId(@SiteId) AS A | |
OUTER APPLY | |
TVF_Webs_NoLock_Id(A.ParentWebId) AS B | |
WHERE | |
(B.SiteId IS NULL OR B.SiteId = @SiteId) | |
END |
In fact, if you want to refer to any of these properties directly from the SPWeb objects of the returned webs, then also no additional call will be made to the database to fetch the properties. Here is the code to demonstrate that:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
SPSite site = SPContext.Current.Site; | |
SPWebCollection subWebs = site.AllWebs; | |
foreach (SPWeb web in subWebs) | |
{ | |
//Code for demo purpose only. | |
var result = web.Title + | |
web.ServerRelativeUrl + | |
web.ID + | |
web.Language + | |
web.WebTemplateId + | |
web.Configuration + | |
web.UIVersionConfigurationEnabled + | |
web.UIVersion + | |
web.MasterUrl + | |
web.CustomMasterUrl; | |
} |
As far as you access only these properties from the SPWeb object, there will be no need to make any more calls to the database.
Now, If you want to refer to any of the other properties of the SPWeb object, things are going to get expensive. For example, if you want to refer to the SPWeb.SiteLogoUrl property, you will get the following result in the Developer Dashboard:
So as you can see SharePoint has to call the proc_GetTpWebMetaDataAndListMetaData procedure for each SPWeb object in order to return the SiteLogoUrl property.
If you use reflector or ILSpy and open the SPWeb Class in the Microsoft.SharePoint.dll , you will see that there are 2 internal methods called InitWeb( ) and InitWebPublic( ) which are responsible for initializing most of the properties of the SPWeb object. These methods in turn call the SPWeb.Request.OpenWebInternal( ) method which actually does the job of calling unmanaged code to open the expensive SPWeb object.
This was indeed a valuable learning for me as it would hugely impact the performance of my code. I hope it was a good learning for you too!