Brothers In Code

...a serious misallocation of .net resources

Moving a "Simplified Configuration" WCF Service From IIS Host to a Self Host

WCF configuration files can get pretty big pretty fast, so the new Simplified Configuration in .Net 4.0 definately interested me.   However there are a couple of errors that make perfect sense but might catch you off guard if you're not reading the fine print.

Error: Service has zero application (non-infrastructure) endpoints

The simple configuration is supposed to create one end point for each base address / contract combination.  So what happend here?  This can be explained by one simple line in the above linked document:

Services hosted under Internet Information Services (IIS) or Windows Process Activation Service (WAS) use the virtual directory as their base address.

Services NOT hosted in one of these environments assume nothing which is a good thing.  It wouldn't make a lot of sense if some console.exe program just randomly grabbed a port to use.  So you are required to specify a base address:


    <services>
      <service name="MyApp.MyService">
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost:51234"/>
          </baseAddresses>
        </host>
      </service>
    </services>

Error: The HttpGetEnabled property of ServiceMetadataBehavior is set to true and the HttpGetUrl property is a relative address, but there is no http base address.

This is due to the following line:


  <serviceMetadata httpGetEnabled="true"/>

You're basically saying that you want the metadata to be exposed via http, but you've provided no http endpoint.  One fix is to set it to false.  Another is to add a second base address:


          <baseAddresses>
            <add baseAddress="net.tcp://localhost:51234"/>
            <add baseAddress="http://localhost:50080"/>
          </baseAddresses>


No rocket science here, but I wanted to post this because the answers I found weren't very specific.
 

Selecting A Row With A Minimum Value

I think everybody has had to do this a dozen times: return a row of data having a minimum value.  The first reaction is to do a subquery in the where clause or as a derived table:


select *
from scan s
join (
  select min(scan_date) as scan_date
  from scan
) s_min on s.scan_date=s_min.scan_date
where rownum=1

A more performant solution is to use analytic functions:


select *

from (
  select s.*, row_number() over (order by s.scan_date) rn
  from scan s)
where rn = 1;

However, I thought this was a relatively simple and database agnostic solution:


select s1.*
from scan s1
left join scan s2 on s1.scan_date>s2.scan_date
where s2.scan_date is null
and rownum=1

This will return the row  where no other row in the same table is older - in other words, the oldest row.  This is probably the worst performer in the bunch but might be useful for an already complicated query.