Devlico.Us
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @devlicious

Derik Whittaker

Thoughts on Software Development, .Net, OOP, Design Patterns and all things cool

March 2008 - Posts

  • Using Linq to access the file system

    Again, this post is another in the recent string of How-to's.  But it is just so hard to resist.  .Net 3.5 has so many cool features, it is just fun to explore them all.

    In today's post I thought it would be fun to use Linq to access the file system.  I thought I would show how to query both for folders and for files.  In each example I will give the non-Linq way and the Linq way.

    Searching for a giving Directory (by name)

    Non-Linq way

    FileInfo[] files = new DirectoryInfo( @"K:\SomeFolder" ).GetFiles();
    
    foreach ( FileInfo file in files )
    {
            if ( file.Name == "SomeFileName.txt" )
    	{
            	have a match, do something now
    	}
    }
    

    Linq way

    var files = from file in new DirectoryInfo(@"K:\SomeFolder").GetFiles()
    	where file.Name == "SomeFileName.txt"
            select file;
    

    Searching for a given File (by name)

    Non-Linq way

    DirectoryInfo[] di = new DirectoryInfo( @"K:\SomeFolder" ).GetDirectories();
    
    foreach ( DirectoryInfo directoryInfo in di )
    {
            if ( directoryInfo.Name == "SubFolderName")
    	{
    		// have a match, do something now
    	}
    }
    

    Linq way

    var folders = from folder in new DirectoryInfo(@"K:\SomeFolder").GetDirectories()
    	where folder.Name == "SubFolderName"
            select folder;
    

    The above Linq code is not better or worse really, just different.  And like I said before, if you are going to be using .Net 3.5, might as well use the new features.

    Till next time,

  • Fun browser stats for Devlicio.us

    Today I was looking through the Google Analytics for our site.  What really interested me was the stats on the various browsers that are used to view our content.

    Broswer Visits %Visits
    Firefox 17,847 47.56%
    I.E. 17,617 46.95%
    Opera 1,071 2.85%
    Safari 583 1.55%
    Mozilla 287 0.76%
         

    I was pleasantly surprised to see that Firefox usage rivals that of IE when viewing our content.  The reason that this kinda surprises me is that according to w3Counter.com, global IE usage is about 63% compared to Firefox's 27%. 

    Anyway, thought it was kinda cool to see that Firefox usage was high for our site.

    BTW, turns out about 5% of our traffic is still using dialup.  WOW, that must suck:)

    Till next time,

  • Sorting List's the .Net 3.5 Way

    This post is another in the recent string of How-to's.  But it is just so hard to resist.  .Net 3.5 has so many cool features, it is just fun to explore them all.

    Ok, so here is the issue we are going to solve today.  We have a list of entities and we need to sort them.  In this post I will show you 3 different ways to accomplish this task, all producing the same result, but using different techniques (hey Peter, go ahead and show me a 4th and better way :) ).

    A little up front declarations.  Each method will use the same list, so to save space I will declare this now.

    List userList = new List
        {
            new User {FirstName = "Andy", LastName = "Tayler"},
            new User {FirstName = "Opie", LastName = "Tayler"},
            new User {FirstName = "Bee", LastName = "Tayler"},
            new User {FirstName = "Barney", LastName = "Fife"},
            new User {FirstName = "Goomer", LastName = "Pile"}
    };
    

    Sort Method 1 -- Using the Sort with IComarer

    public void Sort_OldSchool()
    {
        userList.Sort(new UserCompare());
    }
    
    // Sort class
    private class UserCompare : IComparer<User>
     {
        public int Compare( User x, User y )
        {
        return x.LastName.CompareTo( y.LastName );
    }
    

    The above works, but requires you to create a custom class that implements the IComparer<User> interface to do the trick.

    Sort Method 2 -- Using Lambda and extension methods

    [Test]
    public void Sort_UsingLambda()
    {
    	userList = userList.OrderBy( user => user.LastName ).ToList();
    }
    

    This way works great, it is clean and very readable.

    Sort Method 3 -- Use Linq2Objects

    [Test]
    public void Sort_UsingLinq()
    {
    	userList = ( from u in userList
            	orderby u.LastName, u.FirstName
                    select u ).ToList();
    }
    

    By using Linq you open yourself up to a whole new level of flexibility. You can not only sort (OrderBy), you can filter, return only a select number of rows, etc, etc.  Basically you can do anything that Linq provides.

    As you can see from the above, they all accomplish the same goal but method 2 & 3 are just more fun.  Besides, if you are going to be using .Net 3.5 you might as well use the new features.

    BTW, all the methods (except 3 since it sorts by LastName and FirstName) above produce the following output.
    Barney Fife
    Goomer Pile
    Andy Tayler
    Opie Tayler
    Bee Tayler

    Till next time,

  • Simple way to Convert IEnumerable<Entity> to List<IEntity>

    Today I ran into a case where I needed to convert a result set of IEnumerable<Entity> from a Linq2Sql command to a List<IEntity> in order to return the data back to the caller. 

     

    We all know that giving the following code
    public class Entity : IEntity

    We can do the following
    IEntity myEntity = new Entity();

    However, we cannot do this
    IEnumerable<Entity> myEnumerationList = LoadFromLinq....
    List<IEntity> myList = myEnumerationList;

    The above syntax will cause a runtime exception complaining about invalid cast.  In order to convert the list types we have to do it manually.  Now there are at least 4 ways that I know of that will do this.  I will describe then all here, and give you my take on which one is best.

    Lets take a look at the actual code I had that required me to convert the IEnumeration to a List. (BTW, I am returning a List because I do NOT care about update/change notifications that I could get with a Collection).

    private List GetInformation()
    {
        IEnumerable results = from sui in DBContextInstance().Table
                                                            select sui;
    
        return results.ToList().ConvertAll(new Converter(ent => ent));
    
    }

     

    Method 1 - Works, but clunky

    private List GetInformation()
    {
        IEnumerable results = from sui in DBContextInstance().Table
                                                            select sui;
    
        List returnList = new List();
    
        foreach (Entity myEntity in results)
        {
            returnList.Add(myEntity);
        }
    
        return returnList;
    }

    The above logic works, but is not that great.  The biggest issue I have with this code is it is bloated and mucks up the method.

    Method 2 - Better then 1, but still painful

    private List GetInformation()
    {
        IEnumerable results = from sui in DBContextInstance().Table
                                                            select sui;
    
        return results.ToList().ConvertAll(new Converter(Convert));
    }
    
    // method to do the casting/conversion
    private IEntity Convert(Entity entity)
    {
        return entity;
    }

    This method does pretty much the same thing as method 1, but in place of having a loop, the ConvertAll method calls the newly created Convert method during each iteration.

    Method 3 - Getting better

    private List GetInformation()
    {
        IEnumerable results = from sui in DBContextInstance().Table
                                                            select sui;
    
        return results.ToList().ConvertAll(new Converter(delegate(Entity entity) { return entity; }));
    }

    This method is nice because all the logic is on one line.  This is the same as method 2, but in place of having to create a new method we are using a inline delegate to do the trick.

    Method 4 - Lambda's rock

    private List GetInformation()
    {
        IEnumerable results = from sui in DBContextInstance().Table
                                                            select sui;
    
        return results.ToList().ConvertAll(new Converter(ent => ent));
    }

    Finally we are on to our shortest, and most 'elegant' example.  This one uses a lambda expression in place of the inline delegate and archives the same result.  The only draw back to this method is that if you are not familiar with Lambda's then this solution may be a little off putting.

    Of the 4 different ways described above, I like Method 4.  However method 3 will get you the exact same result and may be easier to follow for someone who does not know/understand Lambda expressions.  If this is the case, then spend the 10 minutes and read up on Lambda's because they are pretty cool and very powerful.

    Till next time,

  • Welcome Sergio to Devlicio.us

    All, I would like to be the first to welcome Sergio Pereira to the Devlicio.us family. 

    I have known Sergio for some time now and I think he will have a lot of great things to say here.  He is a fellow Alt.Net as well as being based out of the Chicago are.

    Again, welcome and let the good times roll

    Till next time,

  • Linq2Sql issue with DateTime fields

    *****
    Update
    *****

    Thanks to the suggestion to Peter Ritchie, this issue is no more.

    Add the following to your Column() attribute and all is well with the world. 
    UpdateCheck = UpdateCheck.WhenChanged

     

    ***** Back to the original post *****

    Another day, another Linq issue...... Starting to get REAL old, REAL fast.

    Today when I came in I noticed that some of my tests were failing.  Upon inspection I realized that the BDBA's on the team had made some changes to one of the tables i was using.  This was not a big issue to me as i am ok with this.  But what did piss me off was how linq worked with my changes.

    The DBA's had added 3 columns to the table [IsActive, CreatedBy, CreatedDate], along with changing some field types (varchar to char, etc).  In order to consume these changes I needed to update my column mappings on my entity, this was not an issue.  However when I went and re-ran my tests i received the following error:
    "System.Data.Linq.ChangeConflictException: Row not found or changed."

    Below is my entity with mappings

    public partial class AccessKey
    {
    	[Column(AutoSync = AutoSync.OnInsert, DbType = "Int NOT NULL IDENTITY", IsPrimaryKey = true, IsDbGenerated = true)]
    	public Int32 AccessKeyID { get; set; }
    
    	[Column(Name = "AccessKey", DbType = "Char(32) NOT NULL", CanBeNull = false)]
    	public string Key { get; set; }
    
    	[Column(DbType = "SmallInt NOT NULL")]
    	public Int32 AccessKeyActionTypeID { get; set; }
    
    	[Column(DbType = "Int")]
    	public Int32 UserID { get; set; }
    
    	[Column(Name = "ProgID", DbType = "Int")]
    	public Int32 ProgramID { get; set; }
    
    	[Column(DbType = "VarChar(10)")]
    	public string PIN { get; set; }
    	
    	[Column(DbType = "Int")]
    	public Int32 RecruitingID { get; set; }
    
    	[Column(DbType = "Bit NOT NULL", IsDbGenerated = true)]
    	public bool IsActive { get; set; }
    
    	[Column(DbType = "VarChar(128) NOT NULL", IsDbGenerated = true)]
    	public string CreatedBy { get; set; }
    
    	[Column(AutoSync = AutoSync.OnUpdate, DbType = "DateTime NOT NULL", IsDbGenerated = true)]
    	public string CreatedDate { get; set; }
    }

    Below is my tests code

    [Test]
    public void CreateAccessKeyInformation_Valid()
    	AccessKeyRepository repository = new AccessKeyRepository();
    	Domain.Entities.AccessKey accessKey = new Domain.Entities.AccessKey { AccessKeyActionTypeID = _tempActionTypeForTests.AccessKeyActionTypeID, Key = keyGenerator.GenerateNewUniqueAccessKey(), PIN = "ertyui", ProgramID = 1, RecruitingID = 2, UserID = 3 };
    	
    	try
    	{
    		const bool expectedResponse = true;
    
    		bool actualResponse = repository.CreateAccessKeyInformation(accessKey);
    		Assert.That(actualResponse, Is.EqualTo(expectedResponse));
    	}
    	finally
    	{
    		repository.DBContextInstance().AccessKey.DeleteOnSubmit(accessKey);
    		repository.DBContextInstance().SubmitChanges();
    	}
    }

    The goal of the test is to ensure i can create and insert valid data.  After the insert is complete I would like to delete the data (good little testers clean up after them selves).

    When I would call the SubmitChanges() method (inside the CreateAccessKeyInformation method) it would throw the above exception.  Upon Googling the issue I came across this post (here).  It appears that Linq has issues with DateTime fields and my Field CreatedDate is causing the issue.

    However, the recommend suggestion from the post on how to resolve this DID NOT work for me.  I tried to AutoSync atrribute to 'Always', 'OnInsert' and 'OnUpdate', none of them worked.  Finally I just removed the column as it is not needed in any known business case.  Although this works for me now, this is WEAK.  I hope there is a way around this in the future.

    If anyone else knows how to solve this, please let me know.

    Till next time,

  • Linq2Sql limitation with abstract base classes

    Ok, I am only a few days into using Linq and I am already getting annoyed.  I have a need to create an abstract base class that will have a few common properties (columns) that will be used by all my inherited classes.  Here is what I WAS wanting to do.

    public abstract class StagedUserInformation
    {
    
    	[Column( DbType = "Int" )]
    	public virtual Int32 UserID { get; set; }
    
    	[Column( DbType = "VarChar(10)" )]
    	public virtual string Pin { get; set; }
    }
    [Table( Name = "AccessKeyUserStagingForMyPI" )]
    public class StagedUserInformationForMyPI : StagedUserInformation
    {
    	// no logic yet
    }

    You will notice that my 2 columns in the base class have the column attribute, and the inherited class has my table attribute.  This is exactly the way I want this to work.  However, when you try to do this you get the following error:
    System.InvalidOperationException: Data member 'Int32 UserID' of type 'AccessKey.Domain.Entities.StagedUserInformation' is not part of the mapping for type 'StagedUserInformationForMyPI'. Is the member above the root of an inheritance hierarchy?

    In order to get around this, here is what I had to do.

    public abstract class StagedUserInformation
    {
    	public virtual Int32 UserID { get; set; }
    	public virtual string Pin { get; set; }
    }
    [Table( Name = "AccessKeyUserStagingForMyPI" )]
    public class StagedUserInformationForMyPI : StagedUserInformation
    {
    
    	[Column(DbType = "Int")]
    	public override Int32 UserID { get; set; }
    
    	[Column(DbType = "VarChar(10)")]
    	public override string Pin { get; set; }
    }

    Having done this, I realized that I do not need an abstract class, but could use an interface so I made the change.

    [Table( Name = "AccessKeyUserStagingForMyPI" )]
    public class StagedUserInformationForMyPI : IStagedUserInformation
    {
    	[Column(DbType = "Int")]
    	public Int32 UserID { get; set; }
    	
    	[Column(DbType = "VarChar(10)")]
    	public string Pin { get; set; }
    }

    I guess what bothers me most is this concept seems pretty simple, but it has not been implemented.  And based on what I read (here) this was NOT implemented on purpose.

    Till next time,

  • Green tests != proven code

    Let me just say this slowly.... Simply because your tests 'pass' does not mean your code has been proven correct or that it works.

    I know from time to time the notion that 'because I test, my code is solid' floats around the blog-a-sphere.  Well, I am here to say, that is a 100% lie.

    Here is a classic example.  Today I was writing a few tests to ensure that our data transaction management was working as expected.  In my test sweet I was going to have 2 tests:

    1. Transaction_EnsureRollbackWorks()
    2. Transaction_EnsureCommitWorks()

    When I setout to write the test for the rollback all was going good.  My test passed and I was happy (kid in a candy store kinda happy :) ).  It was not till I was working on my test for the commit that I was a sad (like a kid who was told he could not eat candy in that candy store :( ).

    When I started to test my commit logic I was not able to pull the newly committed data from the database.  I was perplexed.... what was the issue.  I decided to take a look at the rollback code (I had hijacked most of the logic from that test).  When I started to step through the code I noticed that something was missing.  My call to SubmitChanges() (we are using Linq). 

    Here is the code for the test:

    [Test]
    public void Transaction_EnsureRollbackWorks( )
    {
        RepositoryOverride repository = new RepositoryOverride();
        Domain.Entities.AccessKey accessKey1 = new Domain.Entities.AccessKey { AccessKeyActionTypeID = 1, Key = "123456789", PIN = "ertyui", ProgramID = 1, RecruitingID = 2, UserID = 3 };
        Domain.Entities.AccessKey accessKey2 = new Domain.Entities.AccessKey { AccessKeyActionTypeID = 1, Key = "56789", PIN = "ertyui", ProgramID = 1, RecruitingID = 2, UserID = 3 };
        
        repository.BeginTransaction();
    
        repository.DBContextInstance().AccessKey.InsertOnSubmit( accessKey1 );
        repository.DBContextInstance().AccessKey.InsertOnSubmit( accessKey2 );
        // code was not in the original test repository.DBContextInstance().SubmitChanges();
    
        repository.RollbackTransaction();
    
        // Check to make sure the data is NOT in the DB
        var results = from ak in repository.DBContextInstance().AccessKey
                      where ak.Key == "56789"
                      select ak;
    
        Assert.That( results.Count(), Is.EqualTo( 0 ) );
    }

    If you notice before the repository.RollbackTransaction(); line there is NO call to SubmitChanges().  Because of this my roll back appear to work and then when I attempted to re-query the data it came up empty, which was the expectation.

    The goal to any test is to clearly put your code though its paces, to prove it correct.  However, if you test is bad, or has logic issues you are not proving your code.

    You have been forewarned Green Test != Proven Code

    Till next time,

  • Linq2Sql and AutoIncrement on TinyInt

    Can someone help me with this?  I was trying to insert a record into our DB where the data type was a TinyInt and received this error "The primary key column of type 'TinyInt' cannot be generated by the server. ".

    I did a bit of Googling and found one post where it states the Linq does not support TinyInt for AutoIncrement columns. 

    Is this true?

    Is there a reason?

    I was able to switch the data type to SmallInt and all was good.

    Looking for feedback.

    Till next time,

  • Putting username/password info in the URL Querystring

    Today a friend forwarded me a URL for a software tool that his department just purchases.  This URL contained the UserName/Password needed to access the download site of the software company (no, will not say which company).  When you click the URL you have COMPLETE access to the access keys for the products. 

    https://{RealCompanyAndDomainhere}/i.aspx?InvoiceID={RealInvoiceIDGoeshere}&Password={RealPasswordGoesHere}

    What really surprised me is that a large software company (this one is pretty big) would allow their URL's to contain this information.  With this URL anyone would be allowed to download the software and have 'legal' keys.

    I guess company size/importance does not matter when it comes to security...:(

    BTW, I emailed a contact I have at this company to give them the FYI.  Lets see what comes of this.

    Till next time,

  • App.Config issues when running NUnit via Resharper

    ***** Update *****
    This issue is directly related to a #R 4 EAP issue.  I was using build 755 and this was an issue.  As of build 762, this is no longer an issue.
    ********************
     

    Today I encountered some odd behavior when trying to run some tests against my configuration object.  I am hoping that someone out there has some insight for me.

    My issue

    I have a project that produces an assembly by the name of AccessKey.Domain.Tests.dll.  Because I have a app.config file in the project, the config file is renamed to AccessKey.Domain.Tests.dll.config when the project is compiled.

    The problem is that when I try to access the appSettings value in the config file I am only getting nulls.  For what ever reason, the .net framework thinks my file should be named AccessKey.Domain.Tests.config (notice the .dll is missing from the name).

    I have verified that the framework is in fact trying to pick up the wrong assembly by checking 2 things.

    1. System.AppDomain.CurrentDomain.SetupInformation.ConfigurationFile
    2. ConfigurationManager.OpenExeConfiguration( ConfigurationUserLevel.None ).FilePath

    Both of these have point to using the wrong config file name.  I even tried to set the value in the System.AppDomain.CurrentDomain.SetupInformation.ConfigurationFile property, but that did not work.

    My Resolution (but is lame)

    In order to get this to work, I simply created a config file in my test project named AccessKey.Domain.Tests.config (again, notice the .dll is missing) and set the file to be copied to the output directory at compile time.

    I don't like doing this as it feels dirty as well as it is not testing my system correctly.

     

    Does anyone have a solution for my problem.  In my 2+ years of testing, I have NEVER run into this issue....... HELP!

    Till next time,

  • Automatic Properties, where have you been for the last 8 years????

    With the recent release of .Net 3.5 one of the new features they added is Automatic Properties.

    Automatic Properties allow you to NOT need to create an instance variable for your properties (assuming you only need simply getter/setter functionality), the compiler will do it for you.

    Here is a simple example:

    public string SomeProperty { get; set; }

    Anyway, I have been using .Net 3.5 exclusively for the past few weeks and I have just fallen in love with Automatic Properties.  God I wish this would have been added a LONG TIME AGO..... Oh well

    And before anyone says anything, public member variables are NOT the same.

    Till next time,

    P.S. I have been coding for the past 8 years, I know that .Net has not been out that long.
     

  • Tests make a great To-Do List

    How many times as developers have we made list of things we needed to work on.  Most of the time they are 'tasks' in some sort of task management system.  However, we do not have one of these such systems at work.  So I decided to use 'ignored' tests as my tasks. 

    I did this in 2 ways:

    1. As I was creating the various objects and methods I started creating tests that had the only contained Assert.Ignore("SomeMessageHere").  In the body of the method added a description of what needed to be done.
    2. I also created a list of other tasks that I needed to do (ie finish setting up CI, determining where to get various config information, etc).  These tests were also simply Assert.Ignore.

    I decided to do this because I figured that seeing these tests in my list over and over again would be a good way to remind me of what needed to be done.

    I set these to be Ignores in place of Fail because I don't want these tests to cause my CI process to fail.

    Anyway, for some reason it had never occurred to me that tests could double as a 'To-Do' list, but it works.

    Till next time,

  • Is var the new Dim?

    In C# .Net 3.5 they added the var keyword.  The intent the var keyword is to allow the object type to be implicitly inferred from the expression used to initialize the variable.  However, more often then not I hear people using it because it saves them time typing. 

    So, if the main reason SOME people are using var i have to ask the one simple qusetion

    Is var any different then Dim?  I mean they both have 3 letters.  They both are used to declare variables........ Hum

    *****
    I know that var is NOT the same as dim in the 'CLR' sense, so please do NOT try to explain to me how they are different
    *****


    Till next time, 

  • They all have one thing in common.....

    Test first

    Test during

    Test after

    Answer, Test.

    No matter what style of testing you believe in, they all share one common trait.  They all test your code. 

    So, what is the point of this post you may ask?  Simple.  To me, it does not matter how your tests come to be, but having tests is what is important.

    ***** Yes, I know that the TDD purest believe that testing first provides simpler code, cleaner code, better SoC, etc, etc.  *****

    Till next time,

More Posts Next page »

Our Sponsors

Red-Gate!