Friday, August 31, 2012

COTS

...stands for Commercial, Off the Shelf or Comes off the Shelf

SharePoint runs in ASP.NET 3.5

The last two using statements in my console app (below) where red (angry) in Visual Studio until I right-clicked on the project and set it to be of ASP.NET 3.5.

using System.Configuration;
using System;
using System.Collections.Generic;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Linq;
namespace SharePoint.FSC.AOPC.ConsoleApplication
{
   public class Program
   {
      public static string siteUrl =
            ConfigurationManager.AppSettings["http://fscee42471-2/"];
      public static string subsiteUrl =
            siteUrl + ConfigurationManager.AppSettings["AOPCPortal/"];
      
      static void Main(string[] args)
      {
         Console.WriteLine("SPMetal Console Application");
         Console.WriteLine("Press any key to create dummy data for the Application");
         Console.ReadLine();
         Console.WriteLine("Creating Items...");
         Console.WriteLine("Finished...");
         Console.WriteLine("Press any key to exit.");
         Console.ReadLine();
      }
   }
}

routes for web forms!

http://msdn.microsoft.com/en-us/library/cc668202%28v=vs.90%29.aspx makes web forms routing look pretty easy:

void Application_Start(object sender, EventArgs e)
{
   RegisterRoutes(RouteTable.Routes);
}
   
public static void RegisterRoutes(RouteCollection routes)
{
   routes.Add("BikeSaleRoute", new Route
   (
      "bikes/sale",
      new CustomRouteHandler("~/Contoso/Products/Details.aspx")
   ));
}

Thursday, August 30, 2012

Ayende at Headspring one week ago!

Share photos on twitter with Twitpic

On 8/23/2012, I saw Ayende Rahien (who is really a Mr. Oren Eini) the inventor of Rhino Mocks speak on RavenDB at an open house party at Headspring. Ayende spoke of his attempt to make Raven simple so that users fell into a pit of success. I learned a little about RavenDB from his talk, but I mostly learned about databases is general. Notes:

  • With indexed fields come a performance hit. RavenDB selective shifts resources to make indexes on the fly as needed and then drop memory allocation for them as needed. A pitfall in a traditional database is to add more and more indexes as needed to a database, some of them used only occasionally while always effecting performance. The more indexes, the more of a performance hit you will take on.
  • Everyone loves SELECT * and even so when it is rolled into production! It is only after three months of life in production that things get painful. Traditional testing does not catch the performance lag that cannot be seen until the data is fat. RavenDB will generally only give you back 128 records at once and if you try to hack around this you will only get 1024 max by "being creative." The performance lag as data grows in a traditional system is an example of how an instance of an application (let's say an install of a CRM) that is really used by one important, high-paying client is going to perform poorly compared to an install that is used slightly by a smaller client with a less impressive contract.
  • ACID (Atomic, Consistent, Isolated, Durable) has an alternative called BASE (Basically Available, Soft-state, Eventually Consistent) and discussed here: http://www.johndcook.com/blog/2009/07/06/brewer-cap-theorem-base/
  • CAP (Consistency, Availability and Partition-tolerance) comes with SOA problems that eventual consistency elevates. Otherwise if one partition does not "hear" and update from another, there is a fire-and-forget style failure. Apparently, in the event of a power loss there is a fire-and-forget style failure with eventually consistency within MongoDB which RavenDB addresses and handles better.
  • Ayende hates Guids. I asked him why and he responded: "Have you ever tried to read a Guid to someone over the phone?"
  • If RavenDB suddenly has a lot more reads, it is going to change to put more processing to indexing processing threads. If there is a sudden spike of write, it threads another way. Moderate load takes 20 to 25 milliseconds while high volume loads take 1 to 3 seconds.
  • SELECT Orders WHERE (amount*Qty) > 0 ...in replacing a traditional query like this, RavenDB would just make a new index for total.
  • Query Trends,Date: 2012\-02 ...is a RavenDB query.
    Share photos on twitter with Twitpic
  • MapReduce is offered with RavenDB.
    Share photos on twitter with Twitpic
  • Everything is stored as JSON where a value may be:
    • "" just a string
    • {} another JSON object
    • [] an array
    • [{},{}] an array of complex objects

The 8/23/2012 event, the day before my 38th birthday, marked the first time I had been in Headspring's new office full of new faces. Having been the first employee at Headspring, I was happy to see the success and growth that Dustin Wells has nurtured. He picked the right guys in Jeffrey Palermo and Kevin Hurwitz in the name of spearheading development and teambuilding. It appears Headspring fell down a pit of success. The place seemed very different and I suppose I no longer tie my identity to it, but anyone coming in the door there as a new hire is very lucky indeed. Best wishes Headspring.

Share photos on twitter with Twitpic

a struct cannot have a parameterless constructor

another variation on class

There is no inheirtance for structs.

You need classes in most apps, not structs alone.

structs can be cast to object and back just like classes

K

using Site Columns in ContentTypes in SharePoint 2010

Site Actions > Site Settings > Site Columns ...may be used in ContentTypes in SharePoint 2010. Just splice them into XML as FieldRefs as you might a Field. As far as what their names and ids are, here are two cheat sheets:

your .wsp will be in the debug folder within your bin folder when you build your SharePoint project

Yay!

Wednesday, August 29, 2012

field calculations in SharePoint 2010

See: http://msdn.microsoft.com/en-us/library/bb862071.aspx

lookups in SharePoint 2010

My Elements.xml now looks like this:

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
   <Field ID="{2962C4A9-C298-4393-9234-EAF9CCCD8CA0}" Name="LoginName"
         Type="User" DisplayName="Login Name" StaticName="LoginName"
         Required="TRUE" UserSelectionMode="PeopleOnly" ShowField="Name" />
   <Field ID="{0C5A1104-AD4A-4048-AB08-FAF62814D54B}" Name="LoginIsActive"
         Type="Boolean" DisplayName="Active?" StaticName="LoginIsActive"
         Required="TRUE">
      <Default>1</Default>
   </Field>
   <Field ID="{85ECCAB3-F5A4-4CA9-86E0-BDBC191D64EE}" Name="TypeOfLocation"
         Type="Text" DisplayName="Type Of Location" StaticName="Type Of Location"
         Group="List Content Types" />
   <Field ID="{85EDDAB3-F5A4-4CA9-86E0-BDBC191D64DD}"
            Name="LocationType"
            Type="Lookup"
            DisplayName="LocationType"
            StaticName="Location Type"
            List="Lists/SharePoint.FSC.AOPC-ListInstance1"
            ShowField="TypeOfLocation"
            Required="TRUE"
            Description="This is a list of ways to define the location boundaries for a credit
                  card."
            Group="List Content Types"
            />
   <ContentType ID="0x01004fd59ec931f9478c990051d6fe455f36" Name="CardHolder"
         Group="List Content Types" Description="CardHolder Columns"
         Inherits="FALSE" Version="0">
      <FieldRefs>
         <FieldRef ID="{2962C4A9-C298-4393-9234-EAF9CCCD8CA0}"
               Name="LoginName" />
         <FieldRef ID="{0C5A1104-AD4A-4048-AB08-FAF62814D54B}">
               Name="LoginIsActive" />
      </FieldRefs>
   </ContentType>
   <ContentType ID="0x01004fd59ec931f9478c990051d6fe455f37" Name="LocationTypes"
         Group="List Content Types" Description="Location Types Columns"
         Inherits="FALSE" Version="0">
      <FieldRefs>
         <FieldRef ID="{85ECCAB3-F5A4-4CA9-86E0-BDBC191D64EE}"
               Name="TypeOfLocation" />
      </FieldRefs>
   </ContentType>
   <ContentType ID="0x01004fd59ec931f9478c990051d6fe455f44"
         Name="CardHolderCard" Group="List Content Types"
         Description="CardHolder Card Columns" Inherits="FALSE" Version="0">
      <FieldRefs>
         <FieldRef ID="{85EDDAB3-F5A4-4CA9-86E0-BDBC191D64DD}"
               Name="LocationType" />
      </FieldRefs>
   </ContentType>
</Elements>

 
 

The List value in my Lookup field references the the URL value in an application List Instance...

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
   <ListInstance Title="Location Types"
                        OnQuickLaunch="TRUE"
                        TemplateType="10000"
                        Url="Lists/SharePoint.FSC.AOPC-ListInstance1"
                        Description="My List Instance">
      <Data>
         <Rows>
            <Row>
               <Field Name="TypeOfLocation">Area</Field>
            </Row>
            <Row>
               <Field Name="TypeOfLocation">MSN</Field>
            </Row>
            <Row>
               <Field Name="TypeOfLocation">Office#</Field>
            </Row>
            <Row>
               <Field Name="TypeOfLocation">VISN</Field>
            </Row>
         </Rows>
      </Data>
   </ListInstance>
</Elements>

 
 

Oyekan Olufemi gave me a blob of copy that explained this vital wireup which read: Optional Text. Used to identify the list that is the target of a lookup field (Type="Lookup"). If the target list already exists, the value of the List attribute should be the string representation of the GUID (including braces) that identifies the target list. If the target is the same list as the one that the field belongs to, you can specify "Self". If the target list does not yet exist, the value of the List attribute can be a web-relative URL such as "Lists/My List" but only if the target list is created in the same feature as the one that creates the lookup field. In this case, the value of the List attribute on the Field element must be identical to the value of the Url attribute on the ListInstance element that creates the target list.

 
 

Mistakes I've made in trying to set the List value included using http://fscee42471-2/AOPCPortal/Lists/SharePoint.FSC.AOPC-ListInstance1/ as the URL where such is a deployment off the List Instance. From http://fscee42471-2/AOPCPortal/Lists/SharePoint.FSC.AOPC-ListInstance1/ if I go to: List Tools > List > List Settings I end up at http://fscee42471-2/AOPCPortal/_layouts/listedit.aspx?List=%7BE4D93855%2D549B%2D4AB2%2DAB43%2D6A33BC0E636F%7D and I made the mistake of using {E4D93855-549B-4AB2-AB43-6A33BC0E636F} (cleaned up from %7BE4D93855%2D549B%2D4AB2%2DAB43%2D6A33BC0E636F%7D) as the list value also and this too did not work.

 
 

If I use the CardHolderCard ContentType in a custom list. I will end up with a dropdown that has no default value but which may be changed to allow for selections for:

  1. Area
  2. MSN
  3. Office#
  4. VISN

 
 

Outside of Visual Studio, at a SharePoint deployment, I needed to follow thirteen these steps (which I found at http://msdn.microsoft.com/en-us/library/ff630940.aspx) to create a custom list and associate the CardHolderCard ContentType to it:

  1. Start Internet Explorer and browse to the Web site where you have created the new content type.
  2. In the upper-left corner of the page, click Site Actions and then click More Options.
  3. Click List in the Filter By menu in the Create dialog screen.
  4. Select Custom List.
  5. Type New Announcements as the name and then click Create.
  6. Click List Settings in the SharePoint 2010 ribbon and then under General Settings, click Advanced settings.
  7. Click Yes for Allow management of content types and then click OK.
  8. Under the Content Types section, click the Item content type.
  9. Under Settings, click Delete this content type.
  10. If prompted for confirmation, select OK.
  11. Under the Content Types section, click Add from existing site content types.
  12. From the available site content types list, click New Announcements and then click Add.
  13. Click OK. You should now see the New Announcements content type associated with the New Announcements list.

 
 

After these steps, one may go to: List Tools > List > Modify View > Modify View ...to unhide the lookup column and hide the default columns. (While experimenting I realized that: List Tools > List > Edit List ...opened SharePoint designer.)

 
 

I realized that I could make custom lists in a SharePoint deployment and still redeploy the content in Visual Studio without sabotaging my environment-specific list. This is because only a package is deployed and not the whole of the SharePoint site.

 
 

At Site Actions > Site Settings > Site columns > Create ...one may manually create a lookup column

RoundhousE and UppercuT

...is going to be something akin to Tarantino. There is an article at http://devlicio.us/blogs/rob_reynolds/archive/2010/01/01/two-major-milestones-for-roundhouse-and-uppercut.aspx

Tuesday, August 28, 2012

to make a list instance in a 2010 SharePoint project...

In Visual Studio, I first, in the global Elements.xml, added a ContentType called "LocationTypes" which had just one FieldRef referencing a Text type Field called "TypeOfLocation." I then followed these steps:

  1. At the Solution Explorer, the right-clicked and picked: Add > New Item...
     
  2. I picked "List Definition From Content Type" from the menu that popped up. This will create BOTH a List which is sort of a template/definition for an instantiation AND an actual instantiation called a List Instance.
     
  3. I went through a brief wizard. I picked a content type and gave a friendly name for the list. The list was created with a list instance nested inside of it.
     
  4. The Elements.xml inside of the instance looks like the following. Some of this was generated, but some of this I doctored up. I manually added the four rows and I manually changed the Title value to something easy on the eye.
    <?xml version="1.0" encoding="utf-8"?>
    <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
       <ListInstance Title="Location Types"
                            OnQuickLaunch="TRUE"
                            TemplateType="10000"
                            Url="Lists/SharePoint.FSC.AOPC-ListInstance1"
                            Description="My List Instance">
          <Data>
             <Rows>
                <Row>
                   <Field Name="TypeOfLocation">Area</Field>
                </Row>
                <Row>
                   <Field Name="TypeOfLocation">MSN</Field>
                </Row>
                <Row>
                   <Field Name="TypeOfLocation">Office#</Field>
                </Row>
                <Row>
                   <Field Name="TypeOfLocation">VISN</Field>
                </Row>
             </Rows>
          </Data>
       </ListInstance>
    </Elements>

     
  5. In Schema.xml for the list itself I changed this...
    <ViewFields>
       <FieldRef Name="Attachments">
       </FieldRef>
       <FieldRef Name="LinkTitle">
       </FieldRef>
    </ViewFields>

    ...to this...
    <ViewFields>
       <FieldRef Name="TypeOfLocation">
       </FieldRef>
    </ViewFields>

    ...in order to ensure that my column was unhidden at the list instance and not the default columns.

ValueInjecter is an open source tool akin to AutoMapper

You may download it via NuGet or at: http://valueinjecter.codeplex.com/

Share photos on twitter with Twitpic

cheat sheet on SharePoint field types

http://msdn.microsoft.com/en-us/library/aa979575 is a good cheat sheet on SharePoint field types and how to craft them in XML. It does not however show how one sets a default value which is done with a separate XML tag inside of the given field tag. Olufemi Oyekan showed me this link.

See also: http://msdn.microsoft.com/en-us/library/ms196289.aspx

sample SharePoint 2010 Elements.xml

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
   <Field ID="{2962C4A9-C298-4393-9234-EAF9CCCD8CA0}" Name="LoginName"
         Type="User" DisplayName="Login Name" StaticName="LoginName"
         Required="TRUE" UserSelectionMode="PeopleOnly" ShowField="Name" />
   <Field ID="{0C5A1104-AD4A-4048-AB08-FAF62814D54B}" Name="LoginIsActive"
         Type="Boolean" DisplayName="Active?" StaticName="LoginIsActive"
         Required="TRUE">
      <Default>1</Default>
   </Field>
   <ContentType ID="0x01004fd59ec931f9478c990051d6fe455f36"
            Name="CardHolder"
            Group="List Content Types"
            Description="CardHolder Columns"
            Inherits="FALSE"
            Version="0">
      <FieldRefs>
         <FieldRef ID="{2962C4A9-C298-4393-9234-EAF9CCCD8CA0}"
               Name="LoginName" />
         <FieldRef ID="{0C5A1104-AD4A-4048-AB08-FAF62814D54B}"
               Name="LoginIsActive" />
      </FieldRefs>
   </ContentType>
</Elements>

Hive

The files that make up a SharePoint deployment are called "The Hive." SharePoint uses a content database behind everything, but it also relies upon files heavily. C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14 ...is an example of a path to Hive files. Logs in the Hive show off error messages. Often error messages will be really opaque and one will be given a Correlation Id (guid) to use in finding the "real" error at the logs. ISAPI in the Hive has .dll files. In "Template" you may find the .aspx files and mess with them. Versions of all files are kept in the Hive but the versioning can be flaky. It's not subversion.

Note: Workflows have Correlation Ids too, but they are used for something other than the Correlation Ids of errors.

Monday, August 27, 2012

getting started with SharePoint development

Share photos on twitter with Twitpic

SharePoint configuration files and deployment files are of an XML format. The SharePoint Object Model is typically the tool set used to manipulate SharePoint, however using Data View web parts offering up jQuery is one way to sidestep the Object Model. This is Middle Tier development, I believe. In it, one uses XSLTs to transform list definitions, fields, content types, and list instance creations which are all, again, driven from XML.

When creating a list in SharePoint one will end up with a folder that has an Elements.xml within it and also a Schema.xml within it. There is also a global, application-wide Elements.xml. In a second step in creating a list, FieldRef elements (which define columns) need to go into Elements.xml (either in the global file for access across numerous lists or in a list-specific list for a bounded context). It is then typical to create (within the global Elements.xml) content types which hold collections of FieldRef elements and thus act as canned templates of common list columns. One may make content types inherit from other content types. One will further define columns in the Schema.xml file for a list.

When creating a new global Elements.xml for a SharePoint project, right-click on the project in the Solution Explorer in Visual Studio 2010 and select: Add > New Item... Then pick the "Empty Element" type from SharePoint > 2010 types. Only this will create an appropriate folder to house a global Elements.xml file. If you merely create a folder and make an Elements.xml file in it as much will not work. At the "Features" folder in Visual Studio 2010, right-click and pick "Add Feature" which will allow you to add the Elements.xml file to a deployable feature.

Views constrict what columns may be seen in a list based upon various factors and can act sort of as pseudosecurity in forbidding certain varieties of users from seeing certain things. You may also use Views within web parts to cosmetically/aesthetically style lists and break them up into subsections.

Every time you create a content type a "hidden" mirrored content type is also created. Femi recommends that when using spmetal (LINQ to SharePoint) that one interface with the "hidden" content types.

Feature Explorer allows one to put stuff into (and take stuff back out of) a feature. Feature collections are ASP.NET packages of a .wsp file type. One may rename a .wsp to a .cab to look inside of it in much the same way one may rename a .docx file to a .zip file.

Over 62 million SharePoint 2010 licenses have been sold. Moreover, SharePoint is a for-profit offering from Microsoft and is making the company money. It is not Silverlight or something comparable that Microsoft is just going to flake out on.

Share photos on twitter with Twitpic

Within a SharePoint farm will lie n number of "web apps." Within a web app will live n number of site collections which correspond to spsite objects in C#. Site collections can have n number of "webs" which are actual web sites and correspond to spweb objects in C#. So a spsite is not a web site, a spweb is. This one of the common distinctions that SharePoint developers are asked about in interviews to ensure they are not noobs. The term "site" is often used to refer to an spweb just to make things a little bit more confusing. An spsite (site collection) is a collection of security concerns (permissions, etc.) that may bridge a series of spweb objects. What is the difference between a "web app" and the spweb objects? The "web app" is sort of supersite containing the webs. The default SharePoint site on a server and the SharePoint administrative site are examples of "web apps." A typical url will show the hierarchal arrangement like so: https://www.example.com/site/specificspsite/specificspweb/ ...where herein the second to last chuck of the route references a specific spsite and the last chunk of the route references a specific spweb. A spweb will have SPList (list) and SPFolder (folder) objects. A SPFolder may hold SPFile objects and other SPFolder objects.

When one creates a new SharePoint site in Visual Studio it will be, by default, of ASP.NET 3.5. One may click on the project in the Solution Explorer and press F4 to set the "Site URL" property. This will define where in a URL (within a web app) a spweb will be published to when one right-clicks on the project in the Solution Explorer and picks the "Deploy" option.

There is a way for administrators to go to: Site Actions > Site Settings ...in the UI to then have the option to open a spweb in SharePoint Designer (a free download) to allow for FrontPagesque administration.

One may make a hidden web part and put jQuery within it. This is an ideal place to incorporate jQuery.

User Field Type in SharePoint 2010

http://blog.sandippatil.com/sharepoint-user-type-field-in-schema-xml/ shows how it is done with:

[xml]
<Field
ID="{080FF274-4FAB-43c9-9710-78F3A76925DC}"
Type="User"
DisplayName="My User"
StaticName="MyUser"
Name="User"
Required="TRUE"
UserSelectionMode="PeopleOnly"
ShowField="Name" >
</Field>
[/xml]

Navigation Link in SharePoint

In a lot of my notes I mention a Navigation Link in SharePoint. I found out Friday that this is not a default part of SharePoint 2010 but instead something that we added at HDRI. http://www.youtube.com/watch?v=2svanzd93TI might touch on making navigation links otherwise. I have not yet watched it with audio.

Site Settings > Quick Launch ...might be a better place to go to change the menu up.

CMMI stands for Capability Maturity Model Integration

This is the thing where IBM Consulting is a CMMI level 5 shop and everyone else is chasing them. See: http://en.wikipedia.org/wiki/Capability_Maturity_Model_Integration

Skunkworks

...implies a small team of guys throwing together code for a product or products in a quick/dirty manner to get a new offering up and running. They are blazing a new trail quickly. http://en.wikipedia.org/wiki/Skunkworks_project is a link I found on it.

Saturday, August 25, 2012

CTE is MSSQL

A CTE stands for Common Table Expressions and is a way in MSSQL2005 or greater to do a select after a select without using a temp table. 4 Guys from Rolla offers this example:

WITH ProductAndCategoryNamesOverTenDollars (ProductName, CategoryName,
      UnitPrice) AS
(
   SELECT
      p.ProductName,
      c.CategoryName,
      p.UnitPrice
   FROM Products p
      INNER JOIN Categories c ON
         c.CategoryID = p.CategoryID
   WHERE p.UnitPrice > 10.0
)
SELECT *
FROM ProductAndCategoryNamesOverTenDollars
ORDER BY CategoryName ASC, UnitPrice ASC, ProductName ASC

Wednesday, August 22, 2012

define accounts in Microsoft Project 2010...

...at: File > Info > Manage Accounts

Share photos on twitter with Twitpic

http://ntrajkovski.wordpress.com/2012/06/14/how-to-create-project-server-account-in-ms-project-professional-2010/ is something I found in Googling that touches on this.

VISN stands for Veterans Integrated Services Network.

http://www.usich.gov/member_agency/department_of_veterans_affairs/visn_map/ shows a map of 21 regions called VISNs.

ways to work in SharePoint

  1. SharePoint UI – This is administration directly at the web. SharePoint Foundation is the basic SharePoint package, while SharePoint Server gives you more goodies.
  2. SharePoint Designer – This is a download.
  3. Microsoft Visio
  4. Visual Studio

Tuesday, August 21, 2012

a better cleaner/clearer post on auto-populating uniqueidentifiers in MSSQL

BEGIN TRANSACTION
GO
CREATE TABLE CarPart
   (
   CarPartId uniqueidentifier NOT NULL DEFAULT newid(),
   DescriptionOfObject varchar(255) NOT NULL,
   Price decimal(6,2) NOT NULL,
   AcquiredUpon datetime NOT NULL,
   SoldUpon datetime NULL
   )
GO
ALTER TABLE CarPart ADD CONSTRAINT
   PK_CarPart PRIMARY KEY CLUSTERED
   (
   CarPartId
   ) WITH( STATISTICS_NORECOMPUTE = OFF,
      IGNORE_DUP_KEY = OFF,
      ALLOW_ROW_LOCKS = ON,
      ALLOW_PAGE_LOCKS = ON)
COMMIT

...will allow for guids to automatically be created for the uniqueidentifier column like so:

INSERT INTO CarPart (DescriptionOfObject, Price, AcquiredUpon) VALUES ('2008 Infiniti EX35 Alternator', 115.99, '2008-04-05 00:00:00.000')

Sunday, August 19, 2012

an example of a correlated subquery

SELECT * FROM BigAndSmallNumbers BAS
WHERE BigNumber >
(SELECT AVG(BigNumber)
FROM BigAndSmallNumbers
WHERE SmallNumber = BAS.SmallNumber)

...is an example of a correlated subquery.

 
 

If our BigAndSmallNumbers table looks like this:

SmallNumberBigNumber
218
3234
43456
586746
277
3543
43477
589898
299
3666
49989
598734
599799

 
 

Then our results will be:

SmallNumberBigNumber
277
299
3666
3543
49989
598734
599799

Saturday, August 18, 2012

Contravariance in C# allows for implicitly casting a parent to a child.

int foo = 3;
double bar = foo;
decimal baz = (decimal)bar;

 
 

Notice that above we may implicitly cast foo to bar but that we must explicitly cast bar to baz. The boundaries and differentiation in this case are defined by type, but implicit casts may also be unobtainable given the nature of how the cast works. For example, the following won't fly even though we just saw an example of explicitly casting an int to a double.

List<int> qux = new List<int>() {1, 2, 3};
List<double> quux = qux;

 
 

Whenever we can implicitly cast a more-specific object to a less-specific object, and there are myriads of C# situations in which as much will and will not work, we have an example of covariance. Anytime you may upcast from a child to a parent implicitly you have an example of covariance. Here is an example:

Calico calico = new Calico();
calico.Name = "Patches";
Cat cat = calico;

 
 

If Calico inherits from Cat, you may get away with the casting above, however, as you might imagine, the following code cannot compile:

Cat cat = new Cat();
cat.Name = "Stripes";
Calico calico = cat;

 
 

What we attempt, in vain, immediately above is called contravariance. Any time you implicitly cast from parent to child you have contravariance. In C#, there are many ways in which covariance may be without issue, but when it comes to contravariance, C# 4.0 in a Nutshell by Joseph and Ben Albahari illuminates that there are only two possibilities:

  1. The first is of delegates like so. In this example DoSomethingErOther is a method that takes a Cat and returns a string. We may implicitly cast a Func<Cat, string> to a Func<Calico, string>. If this seems like covariance in disguise in that we are going to ultimately hand a Calico into a method that has Cat in its signature, well, I'm right there with you. I agree.
    Func<Cat, string> corge;
    corge = DoSomethingErOther;
    Func<Calico, string> grault;
    grault = corge;
    Calico calico = new Calico();
    calico.Name = "Patches";
    string garply = grault(calico);

     
  2. For my second trick, I'll need a class and an interface:
    • namespace Whatever.Models
      {
         public class CatMagicMaker : IMagicMaker<Cat>
         {
            public string CastSpell(Cat cat)
            {
               return cat.Name;
            }
         }
      }

       
    • namespace Whatever.Models
      {
         public interface IMagicMaker<in T>
         {
            string CastSpell(T obj);
         }
      }

       
    The other way to do contravariance (it hinges on the in keyword):
    IMagicMaker<Cat> waldo = new CatMagicMaker();
    IMagicMaker<Calico> fred = waldo;
    string plugh = fred.CastSpell(calico);

Friday, August 17, 2012

get above aggregate average values in MSSQL

Share photos on twitter with Twitpic

The values of above average length may be queried out of the table above like so:

SELECT myValue FROM myTable
WHERE LEN(myValue) > (
   SELECT AVG(LEN(myValue)) FROM myTable
)

 
 

If we wanted to filter out the duplicates first, be would still get the same average length (4), but the end result set would be truncated of the dupes. A query for as much is:

CREATE TABLE #myTempTable
(
   myTempValue nvarchar(50)
)
DECLARE @myWord nvarchar(50)
 
DECLARE curs CURSOR FOR
SELECT DISTINCT myValue FROM myTable
OPEN curs
FETCH NEXT FROM curs into @myWord
WHILE @@FETCH_STATUS = 0
   BEGIN
      INSERT INTO #myTempTable (myTempValue)
      VALUES (@myWord)
      FETCH NEXT FROM curs into @myWord
   END
CLOSE curs
DEALLOCATE curs
 
SELECT myTempValue FROM #myTempTable
WHERE LEN(myTempValue) > (
   SELECT AVG(LEN(myTempValue)) FROM #myTempTable
)
 
DROP TABLE #myTempTable

Thursday, August 16, 2012

a much better solution to Anshu Jain's SQL puzzle

A much better solution for this puzzle is:

SELECT myValue FROM myTable
WHERE myValue NOT IN (
   SELECT myValue FROM myTable
   GROUP BY myValue
   HAVING COUNT(myValue) < 2
)
GROUP BY myValue

Anshu Jain's SQL puzzle

Question: If you had one table with one column and some, not all, of the entries were duplicates, how would you find just the duplicates?

Share photos on twitter with Twitpic

 
 

Answer:

CREATE TABLE #myTempTable
(
   myTempCounter int,
   myTempValue nvarchar(50)
)
DECLARE @myNumber int
DECLARE @myWord nvarchar(50)
 
DECLARE curs CURSOR FOR
SELECT Count(myValue) as "counter", myValue
FROM myTable
Group By myValue
 
OPEN curs
FETCH NEXT FROM curs into @myNumber, @myWord
WHILE @@FETCH_STATUS = 0
   BEGIN
      INSERT INTO #myTempTable (myTempCounter, myTempValue)
      VALUES (@myNumber, @myWord)
      FETCH NEXT FROM curs into @myNumber, @myWord
   END
CLOSE curs
DEALLOCATE curs
 
SELECT myTempValue FROM #myTempTable
WHERE myTempCounter > 1
 
DROP TABLE #myTempTable

One may search against Active Directory for a particular account with C#.

Here I began experimenting with Active Directory and I continue in kind here:

using System.Web.Mvc;
using ActiveDirectoryStuff.Helpers;
using ActiveDirectoryStuff.Models;
namespace ActiveDirectoryStuff.Controllers
{
   public class HomeController : Controller
   {
      public ActionResult Index()
      {
         
//the following line requires: <authentication mode="Windows"/> in Web.config
         string name = System.Web.HttpContext.Current.User.Identity.Name;
         ViewBag.Message = name;
         return View();
      }
      
      public ActionResult About()
      {
         return View();
      }
      
      public ActionResult Find(string id)
      {
         if (id.Contains(".")) return RedirectToAction("FindEmailAddress", "Home", new { id =
               id });
         if (id.Contains("\\")) id = id.Replace('\\', '@');
         return RedirectToAction("FindUserName", "Home", new { id = id });
      }
      
      public ActionResult FindEmailAddress(string id)
      {
         string filter = string.Format(MagicStringHelper.SearchFilterTemplate,
               MagicStringHelper.NameEmailMembershipsAndMoreByPosition(1),
               id.ToLower().Trim());
         UserDto userDto = UserDtoCreator.MakeUserDto(filter);
         return View("Find", userDto);
      }
      
      public ActionResult FindUserName(string id)
      {
         if (id.Contains("@")) id = id.Split("@".ToCharArray())[1];
         string filter = string.Format(MagicStringHelper.SearchFilterTemplate,
               MagicStringHelper.NameEmailMembershipsAndMoreByPosition(0),
               id.ToLower().Trim());
         UserDto userDto = UserDtoCreator.MakeUserDto(filter);
         return View("Find", userDto);
      }
   }
}

 
 

Before I explain what is going on, let me show off my two helper classes. The first one just manages magic strings:

using System.Collections.Generic;
namespace ActiveDirectoryStuff.Helpers
{
   public static class MagicStringHelper
   {
      public static string NameOfOurDomain = "aac.dva.va.gov";
      public static string SearchFilterTemplate = "(({0}={1}))";
      public static Dictionary<string,string> NameEmailMembershipsAndMore = new
            Dictionary<string,string>
                        {
                           {"samaccountname","Active Directory Id"},
                           {"mail","Email Address"},
                           {"memberof","Memberships"},
                           {"distinguishedname","Distinguished Name"},
                           {"givenName","First Name"},
                           {"initials","Initials"},
                           {"sn","Surname"},
                           {"objectcategory","Object Category"},
                           {"displayname","Display Name"},
                           {"telephonenumber","Telephone"},
                           {"streetaddress","Street Address"},
                           {"l","City"},
                           {"st","State"},
                           {"postalcode","Postal Code"},
                           {"physicaldeliveryofficename","Office Name"},
                           {"department","Department"},
                           {"description","Description"},
                           {"title","Title"},
                           {"company","Company"},
                           {"manager","Manager"},
                           {"IsAccountLocked","Locked Out?"},
                           {"LockOutTime","Time Of Shut Out"}
                        };
      public static string NameEmailMembershipsAndMoreByPosition(int position)
      {
         int counter = 0;
         foreach (string key in NameEmailMembershipsAndMore.Keys)
         {
            if (counter == position) return key;
            counter++;
         }
         return null;
      }
   }
}

 
 

And now for the stuff you care about! The second helper crawls Active Directory to populate getsetters on a DTO with details on an Active Directory account:

using System.Collections.Generic;
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
using System.Linq;
using ActiveDirectoryStuff.Models;
namespace ActiveDirectoryStuff.Helpers
{
   public class UserDtoCreator
   {
      public static UserDto MakeUserDto(string filter)
      {
         UserDto userDto = CreateDto();
         DirectorySearcher directorySearcher = CreateSearcher();
         directorySearcher.Filter = filter;
         foreach (KeyValuePair<string,string> property in
               MagicStringHelper.NameEmailMembershipsAndMore)
               directorySearcher.PropertiesToLoad.Add(property.Key);
         SearchResult searchResult = directorySearcher.FindOne();
         foreach (KeyValuePair<string, string> property in
               MagicStringHelper.NameEmailMembershipsAndMore)
         {
            if (searchResult.Properties[property.Key].Count != 0)
            {
               if (property.Key ==
                     MagicStringHelper.NameEmailMembershipsAndMoreByPosition(2))
               {
                  int counter = 0;
                  int counterCeiling = searchResult.Properties[property.Key].Count;
                  while (counter < counterCeiling)
                  {
                     userDto.GroupMemberships.Add(searchResult.Properties[property.Key]
                           [counter].ToString());
                     counter++;
                  }
               } else {
                  string value = searchResult.Properties[property.Key][0].ToString();
                  if (value.Trim() != "" && value.Trim() != "0")
                        userDto.FlatDataPoints.Add(property.Value, value);
               }
            }
         }
         return userDto;
      }
      
      private static UserDto CreateDto()
      {
         UserDto userDto = new UserDto();
         userDto.FlatDataPoints = new Dictionary<string, string>();
         userDto.GroupMemberships = new List<string>();
         return userDto;
      }
      
      private static DirectorySearcher CreateSearcher()
      {
         Forest forest = Forest.GetCurrentForest();
         Domain domain = forest.Domains.Cast<Domain>().FirstOrDefault(d => d.Name ==
               MagicStringHelper.NameOfOurDomain);
         DirectoryEntry root = domain.GetDirectoryEntry();
         return new DirectorySearcher(root);
      }
   }
}

 
 

Alright, so what is going on here? Well, as you might guess I have a view model that I am populating. You may see what the DTO looks like in the next blob of code. It has two getsetters, a string/string dictionary and a list of string. I put the various details for a given Active Directory account into the dictionary using the display name as the key and the actual data as the value. There are a couple of exceptions to this rule. I do not add data points that are basically empty or set to zero, and I put the various details of group memberships into the list of string. Before I can do any of this I need to search against Active Directory for the particular individual to report on. In the CreateSearcher() method I grab the forest and then find my particular domain. We will only search against this domain. I ultimately return a DirectorySearcher. I then pass the DirectorySearcher a filter to pinpoint an individual. The filter will look like one of these:

  • ((samaccountname=vafscjaesct))
  • ((mail=tom.jaeschke@va.gov))

SearchResult searchResult = directorySearcher.FindOne(); will then execute the search using the filter. All that remains to be done going forward from this point is to pull data points from searchResult. They will be populated to my view model:

using System.Collections.Generic;
using System.Web.Mvc;
namespace ActiveDirectoryStuff.Models
{
   public class UserDto : Controller
   {
      public Dictionary<string, string> FlatDataPoints;
      public List<string> GroupMemberships;
   }
}

 
 

The view to display my view model:

@model ActiveDirectoryStuff.Models.UserDto
@{
   ViewBag.Title = "Specs";
}
<h2>About the User:</h2>
<table border="0">
   @foreach (KeyValuePair<string, string> flatDataPoint in Model.FlatDataPoints)
   {
      <tr>
         <td nowrap align="right">@flatDataPoint.Key</td>
         <td nowrap style="color: black;">@flatDataPoint.Value</td>
      </tr>
   }
      <tr>
         <td></td>
         <td nowrap>
            <h3>Groups</h3>
            @foreach (string group in Model.GroupMemberships)
            {
               <br />@group
            }
         </td>
      </tr>
</table>

 
 

There is an error with the Distinguished Name designation that I have fixed since taking this picture, but otherwise... the view will bring back something, more or less, like this:

Share photos on twitter with Twitpic

 
 

My Home View is unchanged since my prior blog posting.

@{
   ViewBag.Title = "Home Page";
}
<h2>Your Active Directory Account!</h2>
<p>
   <a href="/Home/Find/@ViewBag.Message.Replace('\\', '@')/">Click here</a> to learn
         more about: @ViewBag.Message
</p>

 
 

I did make a form at the About View to allow one to query for a user by Active Directory Id or email address:

@{
   ViewBag.Title = "About";
}
<h2>Find out about...</h2>
@using (Html.BeginForm("Find", "Home", FormMethod.Post, new { }))
{
   <input name="id"/>
   <button type="submit">Go</button>
}

Wednesday, August 15, 2012

One may get a list of domains from an Active Directory forest in C#. This post shows how.

I am learning to work with Active Directory. Typically, I've done nothing greater than sniff a user's LAN alias in assigning System.Web.HttpContext.Current.User.Identity.Name to a string, but beyond this hat trick lies a large wealth of capabilities in the System.DirectoryServices and System.DirectoryServices.ActiveDirectory namespaces. An Active Directory has a "forest" which may contain numerous domains within it. This allows some boundaries and breakup for a large organization. It is also quicker to search a particular domain than to search the whole of the forest.

I am building a dummy app in the name of experimentation and learning the System.DirectoryServices and System.DirectoryServices.ActiveDirectory namespaces. My About action below shows how to find the forest and get a list of its domains out of it.

using System.Collections.Generic;
using System.Web.Mvc;
using System.Linq;
using System.DirectoryServices.ActiveDirectory;
namespace ActiveDirectoryStuff.Controllers
{
   public class HomeController : Controller
   {
      public ActionResult Index()
      {
         
//the following line requires: <authentication mode="Windows"/> in Web.config
         string name = System.Web.HttpContext.Current.User.Identity.Name;
         ViewBag.Message = name;
         return View();
      }
      
      public ActionResult About(string id)
      {
         string name = id.Replace('@', '\\');
         Forest forest = Forest.GetCurrentForest();
         List<string> domainNames = new List<string>(){};
         domainNames.AddRange (from Domain domain in forest.Domains select
               domain.Name);
         return View(domainNames);
      }
   }
}

 
 

The view for the About action:

@model List<string>
@{
   ViewBag.Title = "Domains";
}
<h2>Domains</h2>
@foreach (string domainName in Model)
{
   @domainName<br />
}

 
 

My Index view is not really related to this posting, yet here it is. I use System.Web.HttpContext.Current.User.Identity.Name to find who the user is (, and, yes, this requires <authentication mode="Windows"/> in the Web.config file). After that, I create a link to the About action and pass it the Active Directory id, but I am not doing anything with this information yet. Forgive the noise.

@{
   ViewBag.Title = "Home Page";
}
<h2>Your Active Directory Account!</h2>
<p>
   <a href="/Home/About/@ViewBag.Message.Replace('\\', '@')/">Click here</a> to learn
         more about: @ViewBag.Message
</p>

Tuesday, August 14, 2012

ModelState.IsValid may be used to sanity check models on the C# side.

I refined the Controller I wrote here to make it so one could navigate to /Home/InvalidTest/ and pass an inappropriate Person object (in this case, a Person who lived to be 132 years old). ModelState.IsValid may be used to sanity check models on the C# side beyond what @Html.ValidationMessageFor may do in a View, and here I use it to catch the oddity of an 132-year-old Person.

using System;
using System.Web.Mvc;
using KeepFeelingValidation.Models;
namespace KeepFeelingValidation.Controllers
{
   public class HomeController : Controller
   {
      public ActionResult Index()
      {
         Person person = new Person();
         person.Name = "Adolph Coors I";
         person.AgeAtDeath = 82;
         person.BirthDay = new DateTime(1847, 2, 4);
         person.IsCrazy = true;
         person.Id = Guid.NewGuid();
         return View(person);
      }
      
      public ActionResult About(Person person)
      {
         if (ModelState.IsValid) return View();
         return View("Invalid");
      }
      
      public ActionResult Invalid()
      {
         return View();
      }
      
      public ActionResult InvalidTest()
      {
         Person person = new Person();
         person.Name = "Adolph Coors I";
         person.AgeAtDeath = 132;
         person.BirthDay = new DateTime(1847, 2, 4);
         person.IsCrazy = true;
         person.Id = Guid.NewGuid();
         return RedirectToAction("About", "Home", person);
      }
   }
}

 
 

If I set a breakpoint at return View("Invalid"); and run the debugger, I can tell that a collection is attached to ModelState containing:

  1. metadata for each of the fields to validate
  2. and if the validations went less-than-lovely for each of the given fields
Share photos on twitter with Twitpic

Yay!

Monday, August 13, 2012

Alonso Robles of Headspring on RavenDB

Share photos on twitter with Twitpic

I saw Alonso Robles of Headspring speak on RavenDB tonight at the Austin .NET User's group.

Share photos on twitter with Twitpic

His talk (a good talk) followed a video he provided at http://info.headspring.com/ravendb-quickstart-video?utm_campaign=RavenDB-Video-Email&utm_source=Email which I was supposed to watch before attending. In writing this, I've still only watched about six minutes of it. In over my head a little bit, I gleamed that Raven uses Lucene for caching and that one when one writes to Raven and then references a Lucene-cached index, that the index may in fact be stale and not contain the update just made if the update just made would fall within the bounds of the select to populate the index (think Views in MSSQL).

Share photos on twitter with Twitpic

The staleness should only linger for maybe two seconds, but it is something you will need to deal with. Naturally, you can refuse to deal with it, but Alonso argued that things work best if you embrace the Lucene caching. Write to Raven. Read from Lucene.

  1. Everything in Raven is JSON and thus everything is a string. If all of your datapoints for a search are floats, then you have to specify that you are searching as if the strings were floats.
  2. Searching by keywords? Use the StandardAnalyzer to crawl copy and break the copy into digestible words for matching.
    Share photos on twitter with Twitpic
  3. There is a GUI editor/record-browser for Raven that is written in Silverlight. (think MSSQL Management Studio Express)
  4. Cool stuff. I will take the time to finish the video clip at http://info.headspring.com/ravendb-quickstart-video?utm_campaign=RavenDB-Video-Email&utm_source=Email

@Html.ValidationMessageFor

using System;
using System.Web.Mvc;
using KeepFeelingValidation.Models;
namespace KeepFeelingValidation.Controllers
{
   public class HomeController : Controller
   {
      public ActionResult Index()
      {
         Person person = new Person();
         person.Name = "Adolph Coors I";
         person.AgeAtDeath = 82;
         person.BirthDay = new DateTime(1847, 2, 4);
         person.IsCrazy = true;
         person.Id = Guid.NewGuid();
         return View(person);
      }
      
      public ActionResult About(Person person)
      {
         return View();
      }
   }
}

 
 

I put these two lines in the master page:

  1. <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
  2. <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

 
 

My home view looked like so:

@model KeepFeelingValidation.Models.Person
@{
   ViewBag.Title = "Home Page";
}
@{ Html.EnableClientValidation(); }
@Html.ValidationSummary(true, "Test was unsuccessful.")
@using (Html.BeginForm("About", "Home", FormMethod.Post, new { }))
{
   @Html.LabelFor(m => m.Name)
   @Html.TextBoxFor(m => m.Name)
   @Html.ValidationMessageFor(m => m.Name)
   <hr/>
   @Html.LabelFor(m => m.AgeAtDeath)
   @Html.EditorFor(m => m.AgeAtDeath)
   @Html.ValidationMessageFor(m => m.AgeAtDeath)
   <hr/>
   @Html.LabelFor(m => m.BirthDay)
   @Html.EditorFor(m => m.BirthDay)
   @Html.ValidationMessageFor(m => m.BirthDay)
   <hr/>
   @Html.LabelFor(m => m.IsCrazy)
   @Html.CheckBoxFor(m => m.IsCrazy)
   @Html.ValidationMessageFor(m => m.IsCrazy)
   <hr/>
   @Html.HiddenFor(m => m.Id)
   <input type="submit" value="submit" />
}

Saturday, August 11, 2012

= () => is a closure

From page 133 of "C# 4.0 in a Nutshell" by Joseph Albahari and Ben Albahari:

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Whatever.Tests
{
   [TestClass]
   public class ClosureTest
   {
      [TestMethod]
      public void Test()
      {
         string whatever = "";
         Action[] actions = new Action[3];
         for (int i = 0; i < 3; i++)
         {
            actions[i] = () => whatever = whatever + i;
         }
         foreach (Action a in actions) a();
         Assert.AreEqual(whatever,"333");
      }
   }
}

Friday, August 10, 2012

Equals O'Arrow explained!

= () => is really a closure, and yet I wrote the following awful, stupid blog posting yesterday...

This suggests that (input parameters) => expression is the basic shape of any Lambda. Therefore...

= () =>

...may be used in creating an anonymous method of sorts to assign a value to a Func like so:

public static Func<DateTime> Now = () => DateTime.UtcNow;

Thursday, August 9, 2012

old school events

A web form's code behind:

using System;
namespace WebApplication
{
   public partial class _Default : System.Web.UI.Page
   {
      private Doubler foo;
      private Doubler bar;
      private Doubler baz;
      
      protected void Page_Load(object sender, EventArgs e)
      {
         foo = new Doubler(17);
         foo.handler += new DoublerEventHandler(OnWhatever);
         bar = new Doubler(18);
         bar.handler += new DoublerEventHandler(OnWhatever);
         baz = new Doubler(19);
         baz.handler += new DoublerEventHandler(OnWhatever);
         foo.DoubleUp();
         bar.DoubleUp();
         baz.DoubleUp();
         string setBreakPointHere = "whatever";
      }
      
      protected static void OnWhatever(Doubler sender, DoublerEventHandlerArgs e)
      {
         sender.EventValue = e.myNumber;
      }
   }
}

 
 

A delegate:

namespace WebApplication
{
   public delegate void DoublerEventHandler(Doubler sender, DoublerEventHandlerArgs
         args);
}

 
 

A child of EventArgs:

using System;
namespace WebApplication
{
   public class DoublerEventHandlerArgs : EventArgs
   {
      public int myNumber;
   }
}

 
 

Finally, the Doubler class:

namespace WebApplication
{
   public class Doubler
   {
      public event DoublerEventHandler handler;
      
      public void DoubleUp()
      {
         DoublerEventHandlerArgs e = new DoublerEventHandlerArgs();
         e.myNumber = OriginalValue * 2;
         
         if (handler != null)
         {
            handler(this, e);
         }
      }
      
      public Doubler(int originalValue)
      {
         this.OriginalValue = originalValue;
      }
      
      public int OriginalValue;
      public int EventValue;
   }
}

 
 

If I set a breakdown at string setBreakPointHere = "whatever"; and debug, I can tell, by inspecting foo, bar, and baz, that I end up with:

 foobarbaz
OriginalValue171819
EventValue343638

 
 

Note that the logic to do the doubling and the logic to make the assignment to EventValue is split up functionally into two very different places in code. This old school event stuff is more gunk touched on in the delegates chapter of C# 4.0 in a Nutshell. As far as delegate trickery goes, I've seen trickery less clunky. Old school, yo.

Objective-C

http://en.wikipedia.org/wiki/Objective-C suggests: "Objective-C is a general-purpose, high-level, object-oriented programming language that adds Smalltalk-style messaging to the C programming language. It is the main programming language used by Apple for the OS X and iOS operating systems and their respective APIs, Cocoa and Cocoa Touch. In Objective-C one does not simply call a method; one sends a message."

http://en.wikipedia.org/wiki/Smalltalk suggests: "The message is the most fundamental language construct in Smalltalk. Even control structures are implemented as message sends. Smalltalk adopts by default a synchronous, single dynamic message dispatch strategy (as contrasted to a synchronous, multiple dispatch strategy adopted by some other object-oriented languages)."

Wednesday, August 8, 2012

Code Contracts

I have read about code contracts some in C# 4.0 in a Nutshell and per this description I see them as a more elegant way to throw exceptions (should a vital requirement be lacking) and NOT another way to unit test. Thanks to Pedro Reys for mentioning Bertrand Meyer of Eiffel fame. He was worth Googling.

Tuesday, August 7, 2012

pessimistic and optimistic locks

This is an article on pessimistic and optimistic locking. A pessimistic lock rolls the whole of an interaction with a table row (from reading to updating) into one transaction, blocking others from altering the row until the transaction is committed or rolled back. In an optimistic lock their is double-checking to ensure that a row did not change between read and rewrite. A transaction will fail in an optimistic lock if there has been a change after all.

Monday, August 6, 2012

Fun Algorithm Stuff

using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Algorithm.Tests
{
   [TestClass]
   public class UnitTests
   {
      [TestMethod]
      public void PrimeNumberAlgorithmTest()
      {
         int counter = 2;
         List<int> primeNumbers = new List<int>();
         while (counter < 101)
         {
            bool isPrimeNumber = true;
            foreach (int primeNumber in primeNumbers.Where(primeNumber => counter %
                  primeNumber == 0))
            {
               isPrimeNumber = false;
            }
            if (isPrimeNumber)
            {
               primeNumbers.Add(counter);
            }
            counter++;
         }
         Assert.AreEqual(primeNumbers[0], 2);
         Assert.AreEqual(primeNumbers[1], 3);
         Assert.AreEqual(primeNumbers[2], 5);
         Assert.AreEqual(primeNumbers[3], 7);
         Assert.AreEqual(primeNumbers[4], 11);
         Assert.AreEqual(primeNumbers[5], 13);
         Assert.AreEqual(primeNumbers[6], 17);
         Assert.AreEqual(primeNumbers[7], 19);
         Assert.AreEqual(primeNumbers[8], 23);
         Assert.AreEqual(primeNumbers[9], 29);
         Assert.AreEqual(primeNumbers[10], 31);
         Assert.AreEqual(primeNumbers[11], 37);
         Assert.AreEqual(primeNumbers[12], 41);
         Assert.AreEqual(primeNumbers[13], 43);
         Assert.AreEqual(primeNumbers[14], 47);
         Assert.AreEqual(primeNumbers[15], 53);
         Assert.AreEqual(primeNumbers[16], 59);
         Assert.AreEqual(primeNumbers[17], 61);
         Assert.AreEqual(primeNumbers[18], 67);
         Assert.AreEqual(primeNumbers[19], 71);
         Assert.AreEqual(primeNumbers[20], 73);
         Assert.AreEqual(primeNumbers[21], 79);
         Assert.AreEqual(primeNumbers[22], 83);
         Assert.AreEqual(primeNumbers[23], 89);
         Assert.AreEqual(primeNumbers[24], 97);
         Assert.AreEqual(primeNumbers.Count, 25);
      }
      
      [TestMethod]
      public void SumTwoAlgorithmTest()
      {
         int[] array = new int[]{7, 8, 14, 1, -12, 27};
         Assert.AreEqual(IsCapableOfReturningSpecificSumForAnyTwoNumbers(array, 15),
               true);
         array = new int[]{ 7, 8, 14, 1, -12 };
         Assert.AreEqual(IsCapableOfReturningSpecificSumForAnyTwoNumbers(array, 15),
               false);
      }
      
      private bool IsCapableOfReturningSpecificSumForAnyTwoNumbers(int[] array, int
            specificSum)
      {
         bool arrayIsLegitimate = true;
         int outerCounter = 0;
         while (outerCounter < array.Count())
         {
            int innerCounter = 0;
            bool isMatchForCounterOne = false;
            while (innerCounter < array.Count())
            {
               if (outerCounter != innerCounter)
               {
                  if (array[outerCounter] + array[innerCounter] == specificSum)
                  {
                     isMatchForCounterOne = true;
                  }
               }
               innerCounter++;
            }
            if (!isMatchForCounterOne)
            {
               arrayIsLegitimate = false;
            }
            outerCounter++;
         }
         return arrayIsLegitimate;
      }
   }
}

Active Directory C# manipulations

This seems a good cheat sheet.

HtmlEncode

Server.HtmlEncode(Input); takes away the greater than and less than signs and Server.HtmlDecode(Input); brings them back. This is a related article.

the at symbol in C#

  • before a variable, allows one to use a reserved key as a variable name
  • before a string value allows one to interpret the string as is without having to escape special characters

see: http://stackoverflow.com/questions/429529/what-does-the-symbol-before-a-variable-name-mean-in-c