<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-1533059771200381582</atom:id><lastBuildDate>Thu, 29 Aug 2024 05:14:11 +0000</lastBuildDate><category>.NET</category><category>Azure</category><category>EpiServer</category><category>Lucene</category><category>SQL</category><category>Sitecore</category><title>adammatusiak</title><description>Adam Matusiak</description><link>http://adammatusiak.blogspot.com/</link><managingEditor>noreply@blogger.com (Adam Matusiak)</managingEditor><generator>Blogger</generator><openSearch:totalResults>14</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1533059771200381582.post-5119058055205492602</guid><pubDate>Mon, 21 Feb 2011 16:31:00 +0000</pubDate><atom:updated>2011-02-21T17:31:16.082+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">SQL</category><title>Disconnecting users from MSSQL database</title><description>When trying to restore database from backup often error saying about connected users is displayed.&lt;br /&gt;
Script below kills all connections to given database.&lt;br /&gt;
Just replace XYZ with required database name.&lt;br /&gt;
Remember that all connections will be dropped without notice.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;USE master

GO

DECLARE @userId varchar(10) 

DECLARE cur CURSOR READ_ONLY      
FOR 
SELECT request_session_id
FROM master.sys.dm_tran_locks     
WHERE resource_type = &#39;DATABASE&#39;     
AND resource_database_id = db_id(&#39;XYZ&#39;)    
GROUP BY request_session_id

OPEN cur     

FETCH NEXT FROM cur INTO @userId      
WHILE (@@fetch_status &lt;&gt; -1)      
BEGIN      
 IF (@@fetch_status &lt;&gt; -2)      
 BEGIN      
  PRINT &#39;Killing connection &#39; + @userId      
  EXEC (&#39;KILL &#39; + @userId)      
 END      
 FETCH NEXT FROM cur INTO @userId      
END      
      
CLOSE cur      
DEALLOCATE cur      
&lt;/pre&gt;</description><link>http://adammatusiak.blogspot.com/2011/02/disconnecting-users-from-mssql-database.html</link><author>noreply@blogger.com (Adam Matusiak)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1533059771200381582.post-31365765166512928</guid><pubDate>Thu, 10 Feb 2011 10:47:00 +0000</pubDate><atom:updated>2011-02-10T11:47:16.947+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">Azure</category><category domain="http://www.blogger.com/atom/ns#">Sitecore</category><title>Deploying Sitecore CMS to Windows Azure using VM Role</title><description>&lt;a href=&quot;http://www.sitecore.net/&quot;&gt;Sitecore CMS&lt;/a&gt; can be deployed to Microsoft Azure using &lt;a href=&quot;http://www.sitecore.net/azure&quot;&gt;Sitecore CMS Azure Edition&lt;/a&gt;, but as a proof of concept I gave it a try to upload it using Virtual Machine (VM) Role.&lt;br /&gt;
&lt;br /&gt;
Using exactly same &lt;a href=&quot;http://adammatusiak.blogspot.com/2011/02/deploying-episerver-cms-to-windows.html&quot;&gt;procedure as with EPiServer&lt;/a&gt; you can deploy &lt;a href=&quot;http://www.sitecore.net/&quot;&gt;Sitecore CMS&lt;/a&gt;. Only change required was updating &lt;strong&gt;aspnet_Membership_GetNumberOfUsersOnline&lt;/strong&gt; procedure as in original it&#39;s not compatible with Azure SQL. So after database migration additional query with code placed below is required:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER OFF
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N&#39;[dbo].[aspnet_Membership_GetNumberOfUsersOnline]&#39;) AND type in (N&#39;P&#39;, N&#39;PC&#39;))
BEGIN
EXEC dbo.sp_executesql @statement = N&#39;CREATE PROCEDURE dbo.aspnet_Membership_GetNumberOfUsersOnline
    @ApplicationName            nvarchar(256),
    @MinutesSinceLastInActive   int,
    @CurrentTimeUtc             datetime
AS
BEGIN
    DECLARE @DateActive datetime
    SELECT  @DateActive = DATEADD(minute,  -(@MinutesSinceLastInActive), @CurrentTimeUtc)

    DECLARE @NumOnline int
    SELECT  @NumOnline = COUNT(*)
    FROM    dbo.aspnet_Users u WITH (NOLOCK),
            dbo.aspnet_Applications a WITH (NOLOCK),
            dbo.aspnet_Membership m WITH (NOLOCK)
    WHERE   u.ApplicationId = a.ApplicationId                  AND
            LastActivityDate &gt; @DateActive                     AND
            a.LoweredApplicationName = LOWER(@ApplicationName) AND
            u.UserId = m.UserId
    RETURN(@NumOnline)
END&#39; 
END
&lt;/pre&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://2.bp.blogspot.com/-ytzSNeFxD8A/TVPAim6OaaI/AAAAAAAAEQ8/CRDEtsp50-k/s1600/sitecore.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;252&quot; width=&quot;320&quot; src=&quot;http://2.bp.blogspot.com/-ytzSNeFxD8A/TVPAim6OaaI/AAAAAAAAEQ8/CRDEtsp50-k/s320/sitecore.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;</description><link>http://adammatusiak.blogspot.com/2011/02/deploying-sitecore-cms-to-windows-azure.html</link><author>noreply@blogger.com (Adam Matusiak)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-ytzSNeFxD8A/TVPAim6OaaI/AAAAAAAAEQ8/CRDEtsp50-k/s72-c/sitecore.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1533059771200381582.post-6667091976394674758</guid><pubDate>Wed, 09 Feb 2011 12:41:00 +0000</pubDate><atom:updated>2011-02-09T13:41:58.593+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">Azure</category><category domain="http://www.blogger.com/atom/ns#">EpiServer</category><title>Deploying EPiServer CMS to Windows Azure using VM Role</title><description>&lt;h2&gt;Intro&lt;/h2&gt;&lt;br /&gt;
This post describes running &lt;a href=&quot;http://world.episerver.com/Documentation/Categories/Products/EPiServer-CMS/&quot;&gt;EPiServer CMS&lt;/a&gt; version 6 on the Windows Azure using &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/gg433107.aspx&quot;&gt;Virtual Machine&lt;/a&gt; (VM) Role Beta Program. The main goal was to take developer Hyper-V machine and deploy it to the cloud as staging environment. &lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Prerequisites&lt;/h2&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Windows Azure account&lt;/li&gt;
&lt;li&gt;VM Role Beta Program enabled (it took over a month to complete)&lt;/li&gt;
&lt;li&gt;basic EPiServer knowledge&lt;/li&gt;
&lt;li&gt;SQL Server 2008 R2&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.microsoft.com/downloads/en/details.aspx?FamilyID=228de03f-3b5a-428a-923f-58a033d316e1&amp;DisplayLang=en&quot;&gt;Microsoft SQL Server 2008 Feature Pack&lt;/a&gt; is required by database migration tool (&lt;a href=&quot;http://sqlazuremw.codeplex.com/&quot;&gt;SQL Azure Migration Wizard&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Visual Studio 2010 or &lt;a href=&quot;http://www.microsoft.com/express/Web/&quot;&gt;Microsoft Visual Web Developer 2010 Express&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.microsoft.com/downloads/en/details.aspx?FamilyID=7a1089b6-4050-4307-86c4-9dadaa5ed018&amp;amp;displaylang=en&quot;&gt;Windows Azure SDK and VS Cloud Service&lt;/a&gt; installed&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;h2&gt;Creating VHD&lt;/h2&gt;&lt;br /&gt;
First Windows Server 2008 R2 is required - I&#39;ve used Windows Server 2008 R2 Enterprise (Full Installation). Additionally it should be installed on a single partition, which is not the default behaviour. There are few posts on how to remove this additional partition but sysprep (described later) fails after those operations - it can be done only during system installation.&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;select Custom (Advanced) instead of Upgrade&lt;/li&gt;
&lt;li&gt;on partition selection screen press Shift + F10 to open console&lt;/li&gt;
&lt;li&gt;run diskpart&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;list disk&lt;/li&gt;
&lt;li&gt;select disk 0&lt;/li&gt;
&lt;li&gt;create partition primary&lt;/li&gt;
&lt;li&gt;exit&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;close console&lt;/li&gt;
&lt;li&gt;refresh&lt;/li&gt;
&lt;li&gt;select created partition&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
After installation go to Server Manager:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;add Role: Web Server (IIS)&lt;/li&gt;
&lt;li&gt;add Feature: .NET Framework 3.5.1 (inside .NET Framework 3.5.1 Features node)&lt;/li&gt;
&lt;/ol&gt;You may need to switch off Windows Update, but it should be inactive by default.&lt;br /&gt;
&lt;strong&gt;You may backup Virtual Machine now to reuse it later.&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Installing Application&lt;/h2&gt;&lt;br /&gt;
Now it&#39;s time to install EPiServer or any other application you&#39;d like to deploy to the could. I&#39;ve used empty EPiServer version 6 with Public Templates. Only web.config change was to switch to SQL Role and Membership providers.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Setting up database&lt;/h2&gt;&lt;br /&gt;
Local database needs to be migrated to Microsoft SQL Azure Database - there&#39;s quite simple way to do it using &lt;a href=&quot;http://sqlazuremw.codeplex.com/&quot;&gt;SQL Azure Migration Wizard&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Because this tool doesn&#39;t clean tables previously filled with data &lt;a href=&quot;http://ozzieperez.net/blog/?p=54&quot;&gt;this script&lt;/a&gt; can be used to remove all tables if another run is required for any reason.&lt;br /&gt;
&lt;br /&gt;
You should modify connectionStrings.config to connect to Azure SQL instance and test if application works.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Finalizing VHD&lt;/h2&gt;&lt;br /&gt;
&lt;strong&gt;It&#39;s highly recommended to backup Virtual Machine now.&lt;/strong&gt;&lt;br /&gt;
Further steps caused it hang during start up until in cloud.&lt;br /&gt;
&lt;br /&gt;
Mount C:\Program Files\Windows Azure SDK\v1.3\iso\wavmroleic.iso as DVD drive and install &lt;strong&gt;WaIntegrationComponents-x64.msi&lt;/strong&gt;. Provide it with valid Administrator password and let it install all the drivers it needs. After reboot run &lt;strong&gt;%windir%\system32\sysprep\sysprep.exe&lt;/strong&gt; enter options as on image below and let Virtual Machine shutdown - now VHD image is ready for deployment.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://1.bp.blogspot.com/_pOL-BmaEa_Y/TVJ7KRKPX0I/AAAAAAAAEQU/w5SI3UZPWQk/s1600/spt.png&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;235&quot; src=&quot;http://1.bp.blogspot.com/_pOL-BmaEa_Y/TVJ7KRKPX0I/AAAAAAAAEQU/w5SI3UZPWQk/s320/spt.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
If you ever start this Virtual Machine again (which is not obvious to succeed) you need to launch sysprep once more.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Creating Management Certificate&lt;/h2&gt;&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Start Visual Studio&lt;/li&gt;
&lt;li&gt;create project of type C# / Cloud / Windows Azure Project.&lt;/li&gt;
&lt;li&gt;click Publish&lt;/li&gt;
&lt;li&gt;Select &#39;Deploy your Windows Azure project to Windows Azure&#39;&lt;/li&gt;
&lt;li&gt;Credentials - select Add... and name it&lt;/li&gt;
&lt;li&gt;Click &#39;Copy the full path&#39; to get Public key path and upload it to Azure&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://2.bp.blogspot.com/_pOL-BmaEa_Y/TVKAyIeh2YI/AAAAAAAAEQc/Qlnka2xjtkU/s1600/cert2.png&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;201&quot; src=&quot;http://2.bp.blogspot.com/_pOL-BmaEa_Y/TVKAyIeh2YI/AAAAAAAAEQc/Qlnka2xjtkU/s320/cert2.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://3.bp.blogspot.com/_pOL-BmaEa_Y/TVKAyKRiCFI/AAAAAAAAEQk/wpFrfhJvS2Q/s1600/cert_upload.png&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;194&quot; src=&quot;http://3.bp.blogspot.com/_pOL-BmaEa_Y/TVKAyKRiCFI/AAAAAAAAEQk/wpFrfhJvS2Q/s320/cert_upload.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Copy subscription ID back to Management Authentication dialog and click OK - it will be verified.&lt;/li&gt;
&lt;li&gt;You can now forget about this project :).&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
&lt;h2&gt;Uploading VHD&lt;/h2&gt;&lt;br /&gt;
Open a Windows Azure SDK Command Prompt as an administrator from Start | All Programs | Windows Azure SDK v1.x.&lt;br /&gt;
Run command below replacing XXXXX and YYYYY with your Subscription Id and Certificate Thumbprint respectively. You should of course provide path to VHD and destination location to reflect your needs.&lt;br /&gt;
&lt;strong&gt;&lt;br /&gt;
csupload Add-VMImage -Connection &quot;SubscriptionId=XXXXX; CertificateThumbprint=YYYYY&quot; -Description &quot;Base image Windows Server 2008 R2&quot; -LiteralPath &quot;D:\VM\AzureTest\Virtual Hard Disks\Clean win 2008 r2.vhd&quot; -Name baseimage.vhd -Location &quot;North Europe&quot;&lt;br /&gt;
&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://1.bp.blogspot.com/_pOL-BmaEa_Y/TVKK2Y7nAFI/AAAAAAAAEQ0/bV3Pe2vhDw0/s1600/upload.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;262&quot; width=&quot;320&quot; src=&quot;http://1.bp.blogspot.com/_pOL-BmaEa_Y/TVKK2Y7nAFI/AAAAAAAAEQ0/bV3Pe2vhDw0/s320/upload.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Anywhere locations are not supported (i.e. Anywhere Europe and Anywhere US).&lt;br /&gt;
&lt;br /&gt;
Statuses visible in Management Portal while uploading:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;pending means uploading&lt;/li&gt;
&lt;li&gt;committed means ready&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;h2&gt;Creating the Service Model (Visual Studio part)&lt;/h2&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Start VS2010&lt;/li&gt;
&lt;li&gt;create Windows Azure Project without any roles&lt;/li&gt;
&lt;li&gt;right-click Roles &amp;gt; Add &amp;gt; New Virtual Machine Role&lt;/li&gt;
&lt;li&gt;in properties of new role &amp;gt; Virtual Hard Disk tab &amp;gt; select account and uploaded VHD&lt;/li&gt;
&lt;li&gt;in Endpoints tab add:&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;name: HttpIn&lt;/li&gt;
&lt;li&gt;type: Input&lt;/li&gt;
&lt;li&gt;protocol: Http&lt;/li&gt;
&lt;li&gt;public port: 80&lt;/li&gt;
&lt;li&gt;private port: 80&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;go to Publish&lt;/li&gt;
&lt;li&gt;Configure Remote Desktop (save certificate to file WITH the private key)&lt;/li&gt;
&lt;li&gt;select Create Service Package Only&lt;/li&gt;
&lt;li&gt;click OK&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
&lt;h2&gt;Creating the Service Model (Management Portal part)&lt;/h2&gt;&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;New Hosted Service - name it, give it URL prefix, choose region and &#39;Do not deploy&#39;&lt;/li&gt;
&lt;li&gt;Add Certificate (select one created in previous step)&lt;/li&gt;
&lt;li&gt;New Production Deployment - name it and select two files created by VS (.cspkg and .cscfg)&lt;/li&gt;
&lt;li&gt;wait...&lt;/li&gt;
&lt;li&gt;wait more...&lt;/li&gt;
&lt;li&gt;wait even more...&lt;/li&gt;
&lt;li&gt;you can connect to IIS using URL on the right&lt;/li&gt;
&lt;li&gt;Connect on the ribbon downloads RDP file&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://3.bp.blogspot.com/_pOL-BmaEa_Y/TVKJ9Yr9SRI/AAAAAAAAEQs/e37FZ7HGJoM/s1600/ready.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;256&quot; width=&quot;320&quot; src=&quot;http://3.bp.blogspot.com/_pOL-BmaEa_Y/TVKJ9Yr9SRI/AAAAAAAAEQs/e37FZ7HGJoM/s320/ready.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Further works&lt;/h2&gt;&lt;br /&gt;
All file system modification on Virtual Machine will be lost when it&#39;s reimaged from uploaded VHD. It may happen because of machine failure or restart. At the moment only data stored in Azure SQL is safe - every change to &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.web.hosting.virtualpathprovider.aspx&quot;&gt;VPP &lt;/a&gt; will be lost. There are two options - to store VPP data in database or in Cloud Storage. There&#39;s a post on this by &lt;a href=&quot;http://blog.bergdaniel.se/post/EPiServer-Azure-Virtual-Path-Provider-part-one.aspx&quot;&gt;Daniel Berg&lt;/a&gt; but I haven&#39;t tried yet.&lt;br /&gt;
&lt;br /&gt;
There&#39;s also licensing issue as EPiServer license is linked either to IP or MAC address. Unfortunately MAC address changes as well during deployment. At the moment I&#39;ve generated new demo license using MAC address obtained from Virtual Machine but it will be lost. Not sure what can be done about it.</description><link>http://adammatusiak.blogspot.com/2011/02/deploying-episerver-cms-to-windows.html</link><author>noreply@blogger.com (Adam Matusiak)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_pOL-BmaEa_Y/TVJ7KRKPX0I/AAAAAAAAEQU/w5SI3UZPWQk/s72-c/spt.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1533059771200381582.post-9023205157015527117</guid><pubDate>Mon, 31 May 2010 15:22:00 +0000</pubDate><atom:updated>2010-05-31T17:23:10.103+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><title>WCF service consumed by jOuery on IIS7</title><description>For this example assume you need to return Info structure (that consists of two strings: Title and Body) that can be queried using it&#39;s Id.&lt;br /&gt;
&lt;br /&gt;
First you have to define data contract:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;namespace Example
{
    [DataContract]
    public class Info
    {
        [DataMember]
        public string Title;

        [DataMember]
        public string Body;
    }
}
&lt;/pre&gt;&lt;br /&gt;
Then interface of the service - it also defines request and response format as JSON (which can be easily consumed in JavaScript).&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;namespace Example
{
    [ServiceContract(Namespace = &quot;&quot;)]
    public interface IGetInfoService
    {
        [OperationContract]
        [WebGet(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
        Info GetInfo(int id);
    }
}
&lt;/pre&gt;&lt;br /&gt;
Service logic just to provide full example :)&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;namespace Example
{
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]    
    public class GetInfoService: IGetInfoService
    {       
        public Info GetInfo(int id)
        {
            return
                new Info 
                    {
                        Title = id.ToString(),
                        Body = &quot;Lorem ipsum&quot;
                    });
        }
    }
}
&lt;/pre&gt;&lt;br /&gt;
WCF service requires also web.config section:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;&amp;lt;system.serviceModel&amp;gt;
        &amp;lt;services&amp;gt;                        
                &amp;lt;service behaviorConfiguration=&quot;GetInfoServiceBehavior&quot; name=&quot;GetInfoService&quot;&amp;gt;
                        &amp;lt;endpoint address=&quot;&quot; behaviorConfiguration=&quot;GetInfoEndpointBehavior&quot; binding=&quot;webHttpBinding&quot; contract=&quot;Example.IGetInfoService&quot;&amp;gt;                                       
                                &amp;lt;/endpoint&amp;gt;
                                &amp;lt;endpoint address=&quot;mex&quot; binding=&quot;mexHttpBinding&quot; contract=&quot;IMetadataExchange&quot; /&amp;gt;
                &amp;lt;/service&amp;gt;
        &amp;lt;/services&amp;gt;
               
        &amp;lt;behaviors&amp;gt;
                &amp;lt;serviceBehaviors&amp;gt;
                        &amp;lt;behavior name=&quot;GetInfoServiceBehavior&quot;&amp;gt;
                                &amp;lt;serviceMetadata httpGetEnabled=&quot;true&quot; /&amp;gt;
                                &amp;lt;serviceDebug includeExceptionDetailInFaults=&quot;false&quot; /&amp;gt;                                                                    
                        &amp;lt;/behavior&amp;gt;
                &amp;lt;/serviceBehaviors&amp;gt;
                &amp;lt;endpointBehaviors&amp;gt;
                        &amp;lt;behavior name=&quot;GetInfoEndpointBehavior&quot;&amp;gt;
                                &amp;lt;enableWebScript /&amp;gt;
                        &amp;lt;/behavior&amp;gt;
                &amp;lt;/endpointBehaviors&amp;gt;
        &amp;lt;/behaviors&amp;gt;
        &amp;lt;serviceHostingEnvironment aspNetCompatibilityEnabled=&quot;true&quot; /&amp;gt;
&amp;lt;/system.serviceModel&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
Consume service using jQuery $.ajax call.&lt;br /&gt;
Params is object that handles all parameters and msg in success function &lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;var params = new Object;
params.id = 10;

$.ajax({
 type: &quot;GET&quot;,
 url: &quot;/Services/GetTheFactsService.svc/GetNextFact&quot;,
 data: params,
 dataType: &quot;json&quot;,
 success: function (msg) {
  $(&quot;.info h3&quot;).html(msg.d.Title);
  $(&quot;.info p&quot;).html(msg.d.Body);
 },
 error: function (msg) {
  alert(msg);
 }
});
&lt;/pre&gt;&lt;br /&gt;
If ISS reports 404 or 500 error results you probably need to register WCF:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;c:
cd &quot;C:\Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation&quot;
servicemodelreg -i
&lt;/pre&gt;Command above registers *.svc handlers for host so if you have other defined for site you have to remove them or go to Handler Mappings section and use Revert To Inherited action.</description><link>http://adammatusiak.blogspot.com/2010/05/wcf-service-consumed-by-jouery-on-iis7.html</link><author>noreply@blogger.com (Adam Matusiak)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1533059771200381582.post-3036244563285296593</guid><pubDate>Fri, 23 Apr 2010 16:21:00 +0000</pubDate><atom:updated>2010-04-23T18:21:38.191+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">Lucene</category><title>Lucene large queries efficiency</title><description>Reading large data sets from &lt;a href=&quot;http://lucene.apache.org/lucene.net/&quot;&gt;Lucene&lt;/a&gt; even after &lt;a href=&quot;http://adammatusiak.blogspot.com/2010/04/speeding-up-lucene-index.html&quot;&gt;adding document cache&lt;/a&gt; can still be slow due to algorithm that loads only 100 results and queries again each time loaded amount is smaller than required. Documentation advises to use HitCollector to speed up but it&#39;s hard to find an example. Big disadvantage of this approach is  no sorting support when HitCollector is used.&lt;br /&gt;
Below you can find example of LuceneHitCollector storing items in LuceneHitCollectorItems and using LuceneSorter.&lt;br /&gt;
LuceneSorter is based on internal Lucene sort algorithm and therefore uses it&#39;s dictionaries built while directory is created. It implements only subset of Lucene capabilities:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;sorting by rank (when empty string is passed to Sort method)&lt;/li&gt;
&lt;li&gt;sorting by string field&lt;/li&gt;
&lt;li&gt;reverse order sorting&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Last code example shows how to use HitCollector. It&#39;s as easy as using Lucene itself and again much faster.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;public class LuceneHitCollectorItem
{
    public float Score;
    public int DocId;
    public Document Doc;
}
&lt;/pre&gt;&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;public class LuceneHitCollector : HitCollector
{        
    private readonly IndexReader reader;
    private List&amp;lt;LuceneHitCollectorItem&amp;gt; docs = new List&amp;lt;LuceneHitCollectorItem&amp;gt;();

    public LuceneHitCollector(IndexReader reader)
    {
        this.reader = reader;
    }

    public override void Collect(int doc, float score)
    {
        Document document = reader.Document(doc);
        docs.Add(
            new LuceneHitCollectorItem
                {
                    DocId = doc,
                    Doc = document,
                    Score = score
                }
            );
    }

    public void Sort(string field, bool reverse)
    {
        LuceneSorter sorter = new LuceneSorter(reader, field, reverse);
        sorter.Sort(docs);
    }

    public int Count
    {
        get
        {
            return docs.Count;
        }
    }

    public LuceneHitCollectorItem Doc(int n)
    {
        return docs[n];
    }
}
&lt;/pre&gt;&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;public class LuceneSorter
{
    private string field;
    private bool reverse;
    private StringIndex index;

    public LuceneSorter(IndexReader reader, string field, bool reverse)
    {
        if (field != &quot;&quot;)
        {
            String fieldName = String.Intern(field);
            index = FieldCache_Fields.DEFAULT.GetStringIndex(reader, fieldName);
        }
        this.field = field;
        this.reverse = reverse;
    }

    public void Sort(List&amp;lt;LuceneHitCollectorItem&amp;gt; docs)
    {
        if (String.IsNullOrEmpty(field))
        {
            docs.Sort(CompareScore);
        }
        else
        {
            docs.Sort(CompareField);
        }
    }

    private int CompareField(LuceneHitCollectorItem a, LuceneHitCollectorItem b)
    {
        int result = index.order[a.DocId] - index.order[b.DocId];
        if (result == 0)
        {
            result = a.DocId - b.DocId;
        }
        return (reverse) ? -result : result;
    }

    private int CompareScore(LuceneHitCollectorItem a, LuceneHitCollectorItem b)
    {
        int result = a.DocId - b.DocId;
        if (a.Score != b.Score)
        {
            result = (a.Score &gt; b.Score) ? 1 : -1;
        }
        return (reverse) ? -result : result;
    }
}
&lt;/pre&gt;&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;LuceneHitCollector collector = new LuceneHitCollector(reader);
searcher.Search(query, collector);
collector.Sort(field, reverse);
for (int index = 0; index &lt; hits.Count; index++)
{
    LuceneHitCollectorItem item = hits.Doc(index);
    Document doc = item.Doc;
    double rank = item.Score;
    //process document
}
&lt;/pre&gt;</description><link>http://adammatusiak.blogspot.com/2010/04/lucene-large-queries-efficiency.html</link><author>noreply@blogger.com (Adam Matusiak)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1533059771200381582.post-3855763811245849384</guid><pubDate>Fri, 23 Apr 2010 16:04:00 +0000</pubDate><atom:updated>2010-04-23T18:22:33.929+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">Lucene</category><title>Speeding up Lucene Index</title><description>&lt;a href=&quot;http://lucene.apache.org/lucene.net/&quot;&gt;Lucene&lt;/a&gt; is indexing and search technology, as well as spellchecking, hit highlighting and advanced analysis/tokenization capabilities. .NET version is automatic Java Lucene port.&lt;br /&gt;
Solution works perfect in most cases but recently I&#39;ve found it too slow. Directory can be stored in file system or in memory. While search indexes are cached in memory document contents are loaded each time from directory. I haven&#39;t checked Java implementation but .NET seems to parse file very slow. File system version requires additionally lots of disc access, which is probably well cached by operating system but not efficent for large indexes (in my case file size is over 500MB). Memory directory implementation tends to leak which is unacceptable.&lt;br /&gt;
Solution below demonstrates how to enable document caching in Lucene.&lt;br /&gt;
Cache needs to be added to FieldsReader class. Code below shows only changes that needs to be made:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Cache directory needs to be added.&lt;/li&gt;
&lt;li&gt;Cache needs to be clear at the end of Close() method.&lt;/li&gt;
&lt;li&gt;Document is returned from cache if already loaded at the beginning of Doc() method.&lt;/li&gt;
&lt;li&gt;Document is added to cache after read in Doc() method.&lt;/li&gt;
&lt;/ul&gt;This change has big memory cost but speeds up large queries even up to 10 times.&lt;br /&gt;
Further optimization can be found &lt;a href=&quot;http://adammatusiak.blogspot.com/2010/04/lucene-large-queries-efficiency.html&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;public sealed class FieldsReader
{
    private SortedList&amp;lt;int,Document&amp;gt; cache=new SortedList&amp;lt;int, Document&amp;gt;();
//---------
    public void Close()
    {
//---------
        cache.Clear();
    }
//---------
    public Document Doc(int n)
    {
        if (cache.ContainsKey(n))
        {
            return cache[n];
        }
//---------
        if (!cache.ContainsKey(n))
        {
            cache.Add(n, doc);
        }
        return doc;
    }
//---------
&lt;/pre&gt;</description><link>http://adammatusiak.blogspot.com/2010/04/speeding-up-lucene-index.html</link><author>noreply@blogger.com (Adam Matusiak)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1533059771200381582.post-169689048618517929</guid><pubDate>Fri, 26 Mar 2010 10:24:00 +0000</pubDate><atom:updated>2010-03-26T11:34:46.036+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><title>Listing your Twitter messages by RSS</title><description>Frequently it&#39;s useful to list your &lt;a href=&quot;http://twitter.com/&quot;&gt;Twitter&lt;/a&gt; messages on web other website or process them in some other way. There are billions of plugins that will allow you to do it but if you need to download them manually it&#39;s best to use RSS. You don&#39;t need to use API so you don&#39;t need to register. Only disadvantage is that you need user ID not his name. You can obtain it from user page - there is a RSS link in right hand column - number in that link is user ID that needs to be passed to the code.&lt;br /&gt;
&lt;br /&gt;
Code below consists of three classes that will get twitts for you. There is also caching so remember that new messages will be fetched only every  UPDATE_EVERY_MINUTES minutes.&lt;br /&gt;
&lt;br /&gt;
Single message:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;public class TwitterCacheItem
    {
        public string Title {get;set;}
        public string Link {get;set;}
        public string Description {get;set;}
    }
&lt;/pre&gt;&lt;br /&gt;
All of them:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;public class TwitterCacheChannel : TwitterCacheItem
    {
        public TwitterCacheChannel()
        {
            Items = new List&lt;twittercacheitem&gt;();
            Loaded = false;
        }

        public DateTime NextUpdateTime { get; set; }
        public bool Loaded { get; set; }
        public List&lt;twittercacheitem&gt; Items { get; private set; }
    }
&lt;/pre&gt;&lt;br /&gt;
And finally the code:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;public class TwitterCache
    {
        private const int UPDATE_EVERY_MINUTES = 60;

        private static SortedList&lt;int, TwitterCacheChannel&gt; cache = new SortedList&lt;int, TwitterCacheChannel&gt;();
        private static object cacheLock = new object();


        public static TwitterCacheChannel GetTwitts(int id)
        {
            TwitterCacheChannel result = null;
            lock (cacheLock)
            {
                if (cache.ContainsKey(id))
                {
                    result = cache[id];
                }
            }
            if ((result==null)||
                (result.NextUpdateTime&amp;lt;DateTime.Now))
            {
                result = FetchTwitts(id);
            }
            return result;
        }

        private static string FetchTwittsUrl(int id)
        {
            return String.Format(&quot;http://twitter.com/statuses/user_timeline/{0}.rss&quot;, id);
        }

        private static TwitterCacheChannel FetchTwitts(int id)
        {
            TwitterCacheChannel result = new TwitterCacheChannel();
            if (id &amp;gt; 0)
            {
                try
                {
                    string url = FetchTwittsUrl(id);
                    string rssText = DownloadWebPage(url);
                    XmlDocument rss = new XmlDocument();
                    rss.LoadXml(rssText);
                    XmlElement channel = rss[&quot;rss&quot;][&quot;channel&quot;];
                    result.Title = channel[&quot;title&quot;].InnerText;
                    result.Link = channel[&quot;link&quot;].InnerText;
                    result.Description = channel[&quot;description&quot;].InnerText;
                    foreach (XmlElement node in channel.SelectNodes(&quot;item&quot;))
                    {
                        TwitterCacheItem item = new TwitterCacheItem();
                        item.Title = node[&quot;title&quot;].InnerText;
                        item.Link = node[&quot;link&quot;].InnerText;
                        item.Description = node[&quot;description&quot;].InnerText;
                        result.Items.Add(item);
                    }
                    result.Loaded = true;
                }
                catch
                {
                }
            }
            result.NextUpdateTime = DateTime.Now.AddMinutes(UPDATE_EVERY_MINUTES);
            lock (cacheLock)
            {
                if (cache.ContainsKey(id))
                {
                    cache[id] = result;
                }
                else
                {
                    cache.Add(id, result);
                }
            }
            return result;
        }

        private static string DownloadWebPage(string url)
        {
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
            request.UserAgent = &quot;.NET Framework/2.0&quot;;
            request.Referer = &quot;http://www.example.com/&quot;;
            WebResponse response = request.GetResponse();
            Stream webStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(webStream);
            string result = reader.ReadToEnd();
            reader.Close();
            webStream.Close();
            response.Close();
            return result;
        }
    }
&lt;/pre&gt;</description><link>http://adammatusiak.blogspot.com/2010/03/blog-post.html</link><author>noreply@blogger.com (Adam Matusiak)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1533059771200381582.post-7275898822590033704</guid><pubDate>Thu, 18 Mar 2010 12:37:00 +0000</pubDate><atom:updated>2010-03-18T13:37:46.160+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><title>Debugging Deadlocks in ASP .NET</title><description>&lt;strong&gt;Deadlock detection&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Deadlock is reported in Event Viewer&lt;br /&gt;
&lt;br /&gt;
Section: Application&lt;br /&gt;
Source: W3SVC-WP&lt;br /&gt;
ID: 2262&lt;br /&gt;
Desc: ISAPI &#39;C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll&#39; reported itself as unhealthy for the following reason: &#39;Deadlock detected&#39;.&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
Section: System&lt;br /&gt;
Source: W3SVC&lt;br /&gt;
ID: 1013&lt;br /&gt;
Desc: A process serving application pool &#39;xxx&#39; exceeded time limits during shut down. The process id was &#39;xxx&#39;.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Server configuration&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
After detecting deadlock IIS kills old and creates new process.&lt;br /&gt;
To prevent it enable the Orphan Worker Process feature.&lt;br /&gt;
&lt;br /&gt;
WARNING: Orphaned Worker Processes must be killed manually to free resources and memory.&lt;br /&gt;
&lt;br /&gt;
cd \Inetpub\adminscripts&lt;br /&gt;
adsutil.vbs SET W3SVC/AppPools/DefaultAppPool/OrphanWorkerProcess TRUE&lt;br /&gt;
&lt;br /&gt;
where DefaultAppPool should be replaced with proper Application Pool name&lt;br /&gt;
List of Application Pools together with Process Ids can be obtained by IISAPP tool (type iisapp in cmd).&lt;br /&gt;
&lt;br /&gt;
You can use &lt;a href=&quot;http://www.microsoft.com/downloads/details.aspx?FamilyID=28bd5941-c458-46f1-b24d-f60151d875a3&amp;displaylang=en&quot;&gt;automatic dump collector&lt;/a&gt; but it seems that better get it by hand.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Dump collecting&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Best way to get dump is using &lt;a href=&quot;http://www.microsoft.com/downloads/details.aspx?FamilyID=28bd5941-c458-46f1-b24d-f60151d875a3&amp;displaylang=en&quot;&gt;DebugDiag&lt;/a&gt; tool.&lt;br /&gt;
Go to Processes tab right-click on selected process and select Create Full Userdump.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Quick dump analysis&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Using DebugDiag you can quickly get info from created dump.&lt;br /&gt;
Right-click on .dmp file and select Analyze Crash/Hang Issue it will show you&lt;br /&gt;
&lt;br /&gt;
Stack trace of each Thread&lt;br /&gt;
All current requests&lt;br /&gt;
But it won&#39;t load symbols for your application.&lt;br /&gt;
Better way is to use WINDBG described below.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Detailed dump analysis&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Procedure is described &lt;a href=&quot;http://blogs.msdn.com/tess/archive/2008/06/12/asp-net-case-study-deadlock-waiting-in-gettosta.aspx&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
1. Install &lt;a href=&quot;http://www.microsoft.com/whdc/devtools/debugging/installx86.mspx&quot;&gt;Debugging Tools&lt;/a&gt;.&lt;br /&gt;
2. Run C:\Program Files\Debugging Tools for Windows\windbg.exe.&lt;br /&gt;
3. Open Crash Dump (form File menu)&lt;br /&gt;
4. Important commands:&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;.symfix binpath
.reload
.loadby sos mscorwks
.cordll -ve -u -l
!threads
~* e !clrstack
&lt;/pre&gt;Last line should display all threads with call stacks and symbols resolved.&lt;br /&gt;
&lt;br /&gt;
System.Threading.Monitor.Enter means that thread waits on lock (...) {...} statement.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;What can possibly go wrong?&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Wrong CLR version&lt;br /&gt;
&lt;br /&gt;
!threads command says:&lt;br /&gt;
&lt;br /&gt;
CLRDLL: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscordacwks.dll:2.0.50727.3053 f:0&lt;br /&gt;
doesn&#39;t match desired version 2.0.50727.3082 f:0&lt;br /&gt;
CLRDLL: Unable to find mscordacwks_x86_x86_2.0.50727.3082.dll by mscorwks search&lt;br /&gt;
CLRDLL: Unable to find &#39;mscordacwks_x86_x86_2.0.50727.3082.dll&#39; on the path&lt;br /&gt;
CLRDLL: Unable to find mscorwks.dll by search&lt;br /&gt;
CLRDLL: ERROR: Unable to load DLL mscordacwks_x86_x86_2.0.50727.3082.dll, Win32 error 0n2&lt;br /&gt;
Failed to load data access DLL, 0x80004005&lt;br /&gt;
&lt;br /&gt;
Solution&lt;br /&gt;
&lt;br /&gt;
Install all Service Packs from &lt;a href=&quot;http://www.microsoft.com/downloads/details.aspx?familyid=6c095bba-6100-4ec9-9c54-6450b0212565&amp;displaylang=en&amp;displaylang=en&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
.NET Framework 2.0 Service Pack 2&lt;br /&gt;
.NET Framework 3.0 Service Pack 2&lt;br /&gt;
.NET Framework 3.5 Service Pack 1</description><link>http://adammatusiak.blogspot.com/2010/03/debugging-deadlocks-in-asp-net.html</link><author>noreply@blogger.com (Adam Matusiak)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1533059771200381582.post-3473717753273023895</guid><pubDate>Wed, 17 Mar 2010 14:49:00 +0000</pubDate><atom:updated>2010-03-17T15:52:00.198+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">EpiServer</category><title>EpiServer - Itera.MultiProperty examples</title><description>&lt;a href=&quot;https://www.coderesort.com/p/epicode/wiki/Itera.MultiProperty&quot;&gt;MultiProperty by Itera&lt;/a&gt; is very useful &lt;a href=&quot;http://www.episerver.com/&quot;&gt;EpiServer&lt;/a&gt; extension.&lt;br /&gt;
&lt;br /&gt;
Two basic ways of using MultiProperty are described on &lt;a href=&quot;http://labs.episerver.com/en/Blogs/Anders-Hattestad/Dates/2008/10/Properties-in-CMS-5/&quot;&gt;a blog by Anders Hattestad&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Basics&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Most common way to use MultiProperty is to create set of fields and then create second property that allows user to create list of those items.&lt;br /&gt;
&lt;br /&gt;
Let&#39;s assume user needs to provide list of ExampleItem.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;public class ExampleItem
    {
        public string Field { get; set; }
        public string Regex { get; set; }        
        public string Default { get; set; }
    }
&lt;/pre&gt;&lt;br /&gt;
First you have to create property that lets user enter single item.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;public class PropertyExampleField : PropertySingleBase
    {
        protected const string PROPERTY_NAME_FIELD = &quot;Field&quot;;
        protected const string PROPERTY_NAME_REGEX = &quot;Regex&quot;;
        protected const string PROPERTY_NAME_DEFAULT = &quot;Default&quot;;

        PropertyDataCollection _innerPropertyCollection;
        protected override PropertyDataCollection InnerPropertyCollection
        {
            get
            {
                if (_innerPropertyCollection == null)
                {
                     _innerPropertyCollection =
                        new PropertyDataCollection
                            {
                                {PROPERTY_NAME_FIELD, new PropertyString()},
                                {PROPERTY_NAME_REGEX, new PropertyString()},
                                {PROPERTY_NAME_DEFAULT, new PropertyString()},
                            };
                }
                return _innerPropertyCollection;
            }
            set { _innerPropertyCollection = value; }
        }

        public string Field
        {
            get { return (PropertyCollection[PROPERTY_NAME_FIELD].Value as string) ?? &quot;&quot;; }
            set { PropertyCollection[PROPERTY_NAME_FIELD].Value = value; }
        }

        public string Regex
        {
            get { return PropertyCollection[PROPERTY_NAME_REGEX].Value as string; }
            set { PropertyCollection[PROPERTY_NAME_REGEX].Value = value; }
        }    

        public string Default
        {
            get { return PropertyCollection[PROPERTY_NAME_DEFAULT].Value as string; }
            set { PropertyCollection[PROPERTY_NAME_DEFAULT].Value = value; }
        }

        public ExampleItem ExampleItem
        {
            get
            {
                return new ExampleItem
                           {
                               Field = Field,
                               Regex = Regex,
                               Default = Default
                           };
            }
        }
    }
&lt;/pre&gt;&lt;br /&gt;
Then you have to create property that lets user create list of items.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;[Serializable]
    [PageDefinitionTypePlugIn(DisplayName = &quot;List of ExampleField&quot;)]
    public class ExampleFieldList : PropertyMultiBase
    {
        PropertyDataCollection baseProperties;
        public override PropertyDataCollection BaseProperties
        {
            get
            {
                if (baseProperties == null)
                {
                    baseProperties = new PropertyDataCollection { { &quot;ExampleField&quot;, new PropertyExampleField() } };
                }
                return baseProperties;
            }
        }

        public List&lt;exampleitem&gt; ExampleItems
        {
            get
            {
                List&lt;exampleitem&gt; result = new List&lt;exampleitem&gt;();
                foreach (PropertyExampleField item in PropertyCollection)
                {
                    result.Add(item.ExampleItem);
                }
                return result;
            }
        }

    }
&lt;/pre&gt;&lt;br /&gt;
&lt;strong&gt;Advanced&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
You can sort fields on save - it will help users to deal with long lists. You can remove empty fields - but you have to remember to let user have one empty so he can add new items. To achieve it override SerializeToXmlNode method in ExampleFieldList class.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;public override System.Xml.XmlNode SerializeToXmlNode(PropertyDataCollection propCollection, PropertyDataCollection basePropertys, Dictionary&lt;string, Guid&gt; newGuids)
        {
            List&lt;propertyexamplefield&gt; fields = new List&lt;propertyexamplefield&gt;();
            bool firstEmpty = true;
            foreach (PropertyData data in propCollection)
            {
                PropertyExampleField field = data as PropertyExampleField;
                if (field == null)
                {
                    continue;
                }
                if (field.Field != &quot;&quot;)
                {
                    fields.Add(field);
                }
                else
                {
                    if (firstEmpty)
                    {
                        fields.Add(field);
                        firstEmpty = false;
                    }
                }
            }
            fields.Sort((a, b) =&gt; a.Field.CompareTo(b.Field));
            PropertyDataCollection newPropCollection = new PropertyDataCollection();
            foreach (PropertyExampleField data in fields)
            {
                newPropCollection.Add(data);
            }
            return base.SerializeToXmlNode(newPropCollection, basePropertys, newGuids);
        }
&lt;/pre&gt;&lt;br /&gt;
You an also force some mandatory items to be placed on the list each time user enters edit mode. To achieve it override ParseToSelf method in ExampleFieldList class.&lt;br /&gt;
&lt;br /&gt;
Example below adds 3 fields named aaa, bbb and ccc.&lt;br /&gt;
Even if user removes any of them they will be recreated next time anyone enters edit mode.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;public override void ParseToSelf(string xml, PropertyDataCollection propCollection, PropertyDataCollection basePropertys)
        {
            base.ParseToSelf(xml, propCollection, basePropertys);            
            string fieldList = &quot;aaa,bbb,ccc&quot;;
            foreach (string part in fieldList.Split(&quot;,&quot;.ToCharArray()))
            {
                string fieldName = part.Trim();
                if (fieldName == &quot;&quot;)
                {
                    continue;
                }
                bool found = false;
                foreach (PropertyData data in propCollection)
                {
                    PropertyExampleField field = data as PropertyExampleField;
                    if (field == null)
                    {
                        continue;
                    }
                    if (field.ExampleItem.Field == fieldName)
                    {
                        found = true;
                        break;
                    }
                }
                if (!found)
                {
                    propCollection.Add(
                        new PropertyExampleField 
                                           {
                                               Name = String.Format(&quot;ExampleField_{0}&quot;, Guid.NewGuid()),
                                               Field = fieldName,
                                               Regex = &quot;&quot;,
                                               Default = &quot;&quot;
                                           });
                }
            }
        }
&lt;/pre&gt;</description><link>http://adammatusiak.blogspot.com/2010/03/episerver-iteramultiproperty-examples.html</link><author>noreply@blogger.com (Adam Matusiak)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1533059771200381582.post-8443448852389218115</guid><pubDate>Tue, 16 Mar 2010 11:12:00 +0000</pubDate><atom:updated>2010-03-16T12:14:23.946+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><title>Binding Fluent NHibernate session to WCF call</title><description>First you should read previous post about &lt;a href=&quot;http://adammatusiak.blogspot.com/2010/03/wcf-session.html&quot;&gt;WCF Session&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
You have to modify the example provided in mentioned post. While binding the Endpoint Extension to the Call Context you need to open and close session.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;public class ExampleEndpointContextInitializer : ICallContextInitializer
    {
        public object BeforeInvoke(InstanceContext instanceContext, IClientChannel channel, Message message)
        {
            bool found = false;
            foreach (IExtension&lt;operationcontext&gt; extension in OperationContext.Current.Extensions)
            {
                if (extension is ExampleEndpointExtension)
                {
                    found = true;
                    break;
                }
            }
            if (!found)
            {
                OperationContext.Current.Extensions.Add(new ExampleEndpointExtension());
            }
            return ExampleSessionProvider.Instance.OpenSession();
        }

        public void AfterInvoke(object correlationState)
        {
            ExampleSessionProvider.Instance.CloseSession(((ISession)correlationState));
            ((IDisposable)correlationState).Dispose();
        }
    }
&lt;/pre&gt;&lt;br /&gt;
The class below will bind Fluent NHibernate session to HttpContext if exists otherwise it will try to bind to WCF context.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;public class ExampleSessionProvider
    {
        private const string SESION_KEY = &quot;SESSION_KEY&quot;;

        private ExampleSessionProvider()
        {

        }

        private static ExampleSessionProvider instance;

        public static ExampleSessionProvider Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new ExampleSessionProvider();
                }
                return instance;
            }
        }

        private ISessionFactory sessionFactory;

        public void CreateSessionFactory()
        {
            sessionFactory = Fluently.Configure();                
                .ExposeConfiguration(BuildSchema)
                .BuildSessionFactory();
            // add more configuration options above !!!
        }

        public ISession GetSession()
        {
            if (HttpContext.Current != null)
            {
                return sessionFactory.GetCurrentSession();
            }
            if (OperationContext.Current != null)
            {
                foreach (IExtension&lt;operationcontext&gt; extension in OperationContext.Current.Extensions)
                {
                    if (extension is ExampleEndpointExtension)
                    {
                        if (((ExampleEndpointExtension)extension).State.ContainsKey(SESION_KEY))
                        {
                            return (ISession)((ExampleEndpointExtension)extension).State[SESION_KEY];
                        }
                    }
                }
            }
            return null;
        }

        public ISession OpenSession()
        {
            ISession session = sessionFactory.OpenSession();

            if (HttpContext.Current != null)
            {
                ManagedWebSessionContext.Bind(
                    HttpContext.Current, session);
            }
            else if (OperationContext.Current != null)            
            {
                foreach (IExtension&lt;operationcontext&gt; extension in OperationContext.Current.Extensions)
                {
                    if (extension is ExampleEndpointExtension)
                    {
                        if (((ExampleEndpointExtension)extension).State.ContainsKey(SESION_KEY))
                        {
                            ((ExampleEndpointExtension)extension).State.Remove(SESION_KEY);
                        }
                        ((ExampleEndpointExtension)extension).State.Add(SESION_KEY, session);
                    }
                }
            }
            return session;
        }

        public void CloseSession()
        {
            CloseSession(null);
        }

        public void CloseSession(ISession session)
        {
            if ((session != null) &amp;&amp; (HttpContext.Current != null))
            {
                session = ManagedWebSessionContext.Unbind(HttpContext.Current, sessionFactory);
            }
            if (session != null)
            {
                if (session.Transaction != null &amp;&amp;
                    session.Transaction.IsActive)
                {
                    session.Transaction.Rollback();
                }
                else
                {
                    session.Flush();
                }
                session.Close();
            }
        }

        private static void BuildSchema(Configuration config)
        {
            config.SetProperty(&quot;current_session_context_class&quot;, &quot;managed_web&quot;);
        }
    }
&lt;/pre&gt;&lt;br /&gt;
Before binding to HttpContext you need to create HttpModule described in post about &lt;a href=&quot;http://adammatusiak.blogspot.com/2010/03/binding-fluent-nhibernate-session-to.html&quot;&gt;Binding Fluent NHibernate session to HttpContext&lt;/a&gt; or you can remove parts related to HttpContext and bind always to WCF call.</description><link>http://adammatusiak.blogspot.com/2010/03/binding-fluent-nhibernate-session-to_16.html</link><author>noreply@blogger.com (Adam Matusiak)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1533059771200381582.post-5437973183934255203</guid><pubDate>Tue, 16 Mar 2010 11:10:00 +0000</pubDate><atom:updated>2010-03-16T12:10:17.268+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><title>Binding Fluent NHibernate session to HttpContext</title><description>It is very useful and common practice to bind Fluent NHibernate session to HttpContext. Easiest way to do it is to create HttpModule.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;public class ExampleSessionModule : IHttpModule
    {
        public void Init(HttpApplication context)
        {
            context.BeginRequest += OpenSession;
            context.EndRequest += CloseSession; 
        }

        private void OpenSession(object sender, EventArgs e)
        {
            ExampleSessionProvider.Instance.OpenSession();            
        }
        
        private void CloseSession(object sender, EventArgs e)
        {
            ExampleSessionProvider.Instance.CloseSession();
        } 

        public void Dispose()
        {
            
        }
    }
&lt;/pre&gt;&lt;br /&gt;
The you just need a session provider.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;public class ExampleSessionProvider
    {
        private const string SESION_KEY = &quot;SESSION_KEY&quot;;

        private ExampleSessionProvider()
        {

        }

        private static ExampleSessionProvider instance;

        public static ExampleSessionProvider Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new ExampleSessionProvider();
                }
                return instance;
            }
        }

        private ISessionFactory sessionFactory;

        public void CreateSessionFactory()
        {
            sessionFactory = Fluently.Configure();                
                .ExposeConfiguration(BuildSchema)
                .BuildSessionFactory();
            // add more configuration options above !!!
        }

        public ISession GetSession()
        {
            if (HttpContext.Current != null)
            {
                return sessionFactory.GetCurrentSession();
            }           
            return null;
        }

        public ISession OpenSession()
        {
            ISession session = sessionFactory.OpenSession();
            ManagedWebSessionContext.Bind(HttpContext.Current, session);            
            return session;
        }

        public void CloseSession()
        {
            ISession session = ManagedWebSessionContext.Unbind(HttpContext.Current, sessionFactory);            
            if (session != null)
            {
                if (session.Transaction != null &amp;&amp;
                    session.Transaction.IsActive)
                {
                    session.Transaction.Rollback();
                }
                else
                {
                    session.Flush();
                }
                session.Close();
            }
        }

        private static void BuildSchema(Configuration config)
        {
            config.SetProperty(&quot;current_session_context_class&quot;, &quot;managed_web&quot;);
        }
    }
&lt;/pre&gt;&lt;br /&gt;
And a bit of web.config configuration:&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;&amp;lt;system.web&amp;gt;
&amp;lt;httpModules&amp;gt;
&amp;lt;add name=&quot;ExampleSessionModule&quot; type=&quot;Example.Session.ExampleSessionModule, Example&quot; /&amp;gt;
&amp;lt;/httpModules&amp;gt;
&amp;lt;/system.web&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
OR (depending on IIS version)&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;&amp;lt;system.webServer&amp;gt;
&amp;lt;modules&amp;gt;
&amp;lt;add name=&quot;ExampleSessionModule&quot; type=&quot;Example.Session.ExampleSessionModule, Example&quot; /&amp;gt;
&amp;lt;/modules&amp;gt;
&amp;lt;/system.webServer&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
Last thing to do is to create session factory in Application Start event.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;protected void Application_Start(Object sender, EventArgs e)
{
    ExampleSessionProvider.Instance.CreateSessionFactory();
}
&lt;/pre&gt;</description><link>http://adammatusiak.blogspot.com/2010/03/binding-fluent-nhibernate-session-to.html</link><author>noreply@blogger.com (Adam Matusiak)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1533059771200381582.post-9196769025264958231</guid><pubDate>Mon, 15 Mar 2010 17:40:00 +0000</pubDate><atom:updated>2010-03-16T12:13:23.911+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><title>WCF Session</title><description>You may need to define object that behaves like HttpSession and bind it to the WCF request. It&#39;s pretty useful when you want to keep Fluent NHibernate session opened during WCF call.&lt;br /&gt;
&lt;br /&gt;
First define the Endpoint Extension that will hold the session state.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;public class ExampleEndpointExtension : IExtension&lt;operationcontext&gt;
    {
        public ExampleEndpointExtension()
        {
            State = new Dictionary&lt;string, object&gt;();
        }

        public IDictionary&lt;string, object&gt; State { get; private set; }

        public void Attach(OperationContext owner) { }
        public void Detach(OperationContext owner) { }
    }
&lt;/pre&gt;&lt;br /&gt;
Then you need to bind it to the Call Context.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;public class ExampleEndpointContextInitializer : ICallContextInitializer
    {
        public object BeforeInvoke(InstanceContext instanceContext, IClientChannel channel, Message message)
        {
            bool found = false;
            foreach (IExtension&lt;operationcontext&gt; extension in OperationContext.Current.Extensions)
            {
                if (extension is ExampleEndpointExtension)
                {
                    found = true;
                    break;
                }
            }
            if (!found)
            {
                OperationContext.Current.Extensions.Add(new ExampleEndpointExtension());
            }
            return new object();
        }

        public void AfterInvoke(object correlationState)
        {            
        }
    }
&lt;/pre&gt;&lt;br /&gt;
Last class to implement is Endpoint Behaviour Extension.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;public class ExampleEndpointBehavior : BehaviorExtensionElement,IEndpointBehavior
    {

        public override Type BehaviorType
        {
            get { return typeof(ExampleEndpointBehavior); }
        }

        protected override object CreateBehavior()
        {
            return new ExampleEndpointBehavior();
        }

        public void Validate(ServiceEndpoint endpoint)
        {            
        }

        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {            
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint,
            EndpointDispatcher endpointDispatcher)
        {
            foreach (DispatchOperation operation in endpointDispatcher.DispatchRuntime.Operations)
            {
                operation.CallContextInitializers.Add(new ExampleEndpointContextInitializer());
            }
        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {            
        }
    }
&lt;/pre&gt;&lt;br /&gt;
You should add your extension in web.config (or app.config).&lt;br /&gt;
&lt;strong&gt;Remember to define assembly together with version and culture.&lt;/strong&gt; There&#39;s a bug in framework that will cause load fail if you omit it.&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;&amp;lt;behaviorextensions&amp;gt;
    &amp;lt;add name=&quot;ExampleBehaviorExtension&quot; type=&quot;Example.Session.ExampleEndpointBehavior, Example, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null&quot; /&amp;gt;
&amp;lt;/behaviorExtensions&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
Now you can use it:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;foreach (IExtension&lt;operationcontext&gt; extension in OperationContext.Current.Extensions)
{
    if (extension is ExampleEndpointExtension)
    {
        ((ExampleEndpointExtension)extension).State[&quot;SESSION_ITEM&quot;] = &quot;test&quot;;
    }
}
&lt;/pre&gt;&lt;br /&gt;
Example of usage in next post &lt;a href=&quot;http://adammatusiak.blogspot.com/2010/03/binding-fluent-nhibernate-session-to_16.html&quot;&gt;Binding Fluent NHibernate session to WCF call&lt;/a&gt;.</description><link>http://adammatusiak.blogspot.com/2010/03/wcf-session.html</link><author>noreply@blogger.com (Adam Matusiak)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1533059771200381582.post-3291942360424798015</guid><pubDate>Mon, 15 Mar 2010 15:35:00 +0000</pubDate><atom:updated>2010-03-15T16:36:44.158+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><title>Fluent NHibernate - List of Int as String</title><description>Having field of type List&lt;int&gt; it is sometimes worthy to save it in database as string rather than create separate table just to keep few values per record.&lt;br /&gt;
It seems to be completely wrong from design point of view but can be much cleaner solution when you have just few values per record.&lt;br /&gt;
&lt;br /&gt;
To map this easily in Fluent create just two classes.&lt;br /&gt;
Then just define your field as IList&lt;int&gt;.&lt;br /&gt;
&lt;br /&gt;
User type convention:&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;public class IntListConvention : IUserTypeConvention
    {
        public bool Accept(IProperty target)
        {
            return target.PropertyType == typeof(IList&lt;int&gt;);
        }

        public void Apply(IProperty target)
        {
            target.CustomTypeIs(typeof(IntListUserType));
        }

        public bool Accept(Type type)
        {
            return type == typeof(IList&lt;int&gt;);
        }
    }
&lt;/pre&gt;&lt;br /&gt;
And new user type:&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;class IntListUserType : IUserType
    {
        public new bool Equals(object x, object y)
        {
            return x != null &amp;&amp; x.Equals(y);
        }

        public int GetHashCode(object x)
        {
            return x.GetHashCode();
        }

        object IUserType.NullSafeGet(IDataReader rs, string[] names, object owner)
        {
            string stringValue = (string) NHibernateUtil.String.NullSafeGet(rs, names[0]) ?? String.Empty;
            List&lt;int&gt; result = new List&lt;int&gt;();
            foreach (string stringItem in stringValue.Split(&quot;,&quot;.ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
            {
                int item;
                if (Int32.TryParse(stringItem, out item))
                {
                    result.Add(item);
                }
            }
            return result;
        }

        public void NullSafeSet(IDbCommand cmd, object value, int index)
        {
            StringBuilder stringValue = new StringBuilder();
            List&lt;int&gt; result = value as List&lt;int&gt;;
            if (value != null)
            {
                foreach (int item in result)
                {
                    if (stringValue.Length &gt; 0)
                    {
                        stringValue.Append(&quot;,&quot;);
                    }
                    stringValue.Append(item);
                }
            }
            ((IDataParameter)cmd.Parameters[index]).Value = stringValue.ToString();
        }

        public object DeepCopy(object value)
        {
            return value;
        }

        public object Replace(object original, object target, object owner)
        {
            return original;
        }

        public object Assemble(object cached, object owner)
        {
            return cached;
        }

        public object Disassemble(object value)
        {
            return value;
        }

        public SqlType[] SqlTypes
        {
            get
            {
                return new[] { new SqlType(DbType.String, 1000) };
            }
        }

        public Type ReturnedType
        {
            get
            {
                return typeof(List&lt;int&gt;);
            }
        }

        public bool IsMutable
        {
            get
            {
                return false;
            }
        }
    }
&lt;/pre&gt;</description><link>http://adammatusiak.blogspot.com/2010/03/fluent-nhibernate-list-as-string.html</link><author>noreply@blogger.com (Adam Matusiak)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1533059771200381582.post-3715178065211864118</guid><pubDate>Mon, 15 Mar 2010 15:09:00 +0000</pubDate><atom:updated>2010-03-15T16:16:29.047+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">SQL</category><title>Shrinking MSSQL log files</title><description>Best solution I&#39;ve found below.&lt;br /&gt;
You just have to replace XYZ with database name in few places.&lt;br /&gt;
You can also uncomment print to get filename.&lt;br /&gt;
Yes, I know it would be useful to have version that iterates through all the databases - I&#39;m just too lazy.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;postCode&quot;&gt;alter database XYZ set recovery simple
GO
alter database XYZ set recovery full
GO
use XYZ
GO
declare @filename sysname
select @filename=Name from sys.database_files where Type=1
--print @filename
DBCC Shrinkfile(@filename,100) 
GO
alter database XYZ set recovery bulk_logged
GO
&lt;/pre&gt;</description><link>http://adammatusiak.blogspot.com/2010/03/shrinking-mssql-log-files.html</link><author>noreply@blogger.com (Adam Matusiak)</author><thr:total>0</thr:total></item></channel></rss>