Tuesday 20 January 2009

LINQ to Entities and the “Collection was modified” exception – A solution!

I’ve found that something that is a common mistake when dealing with collections.  Say I want to go through a list of objects and delete every one that matches a certain criteria.  The simplest code would be something like this:

foreach (Item item in _Entities.Item)
{
    if (/* criteria */)
    {
        _Entities.Item.Remove(item);
    }
}

But that’s not going to work.  When the Remove method is run you will get an exception:

{"Collection was modified; enumeration operation may not execute."}    System.Exception {System.InvalidOperationException}

Ok, so if you think about it it makes sense really, you’re trying to remove an item from the enumeration that you’re currently enumerating through.  But what’s the solution?

Turns out there are many ways you can tackle this problem.  One way is to write each of your delete segments so that you build a list of items to delete first and then delete them from the master list.  It works but it’s a lot of extra code.  Another option is to turn the Colleciton into an array before looping through it and deleting the items.

I like this solution better:

public void RemoveIf<T>(ICollection<T> collection, Predicate<T> match)
{
    List<T> removed = new List<T>();
    foreach (T item in collection)
    {
        if (match(item))
        {
            removed.Add(item); 
        }
    }
 
    foreach (T item in removed)
    {
        collection.Remove(item);
    }
 
    removed.Clear();
}

I’ve written my own helper method to remove an item if it meets a certain criteria.  The helper method will take a Predicate (the same as the Collection.Exists method) and if an items in the collection match the Predicate it will add them to a list, then cycle through the list and remove them.

To implement it use code similar to the following:

RemoveIf(_Entities.Item, delegate(Item i) { return /* criteria */; });

Which is the same style of code you would use if you were trying to implement the Collection.Exists method.  If you wanted to delete all the items from one list if they exist in another, you can of course chain the Exists method into the RemoveIf helper also like so:

RemoveIf(_Entities.Item, delegate(Item itemRemove) 
{
    return !otherList.Exists(delegate(Item itemSearch) 
    { 
        return itemSearch.CustomerID == itemRemove.CustomerID; 
    });
});

But the downside is that the code will get a little confusing for people who haven’t used delegates much, or at all.

Wednesday 14 January 2009

LINQ Best Practice 1 – The Repository Pattern

I’ve been using LINQ a lot with my new project, in particular with the Entity Framework.  I have learned a lot about good practices with LINQ and I figured it would be a good idea to post them up here.  Contained in these posts are all those things I’ve learned and suggest could be useful to you.  They are best practices that work for me, if they work for you then great, but everyone’s solution is different.

Use the Repository Pattern

I can’t stress this enough, if you’re going to use LINQ to Entities then you will benefit enormously from the repository pattern, in particular if Unit Testing and / or TDD is important to you.  The repository pattern defines that you create an interface to your data source within a context and only use this interface for retrieving the data.  Your unit tests for controllers or business logic can then mock the interface into the data to provide logical feedback for the tests.

Here is an example repository for the Item table within my database.  I have a table called Item and I define standard methods for my repositories to implement, Get, Save, Search etc.

This is the interface:

public interface IItemRepository
{
    Item Get(int itemCodeID);
    List<ValidationErrorResult> Save(Item item);
    void Delete(Item item);
    List<ValidationErrorResult> Add(Item item);
    List<Item> Search(string name, string description, int pageNumber, int itemsPerPage);
}

I like to return lists, some people may wish to return IQueryable.  If you return an IQueryable then you’re accepting that the data may not be physically fetched from the database when within the repository source.  In our project I believe it is better to be in control of when we get the data, but this is not for everyone.  There is a great article about returning List over IQueryable or not here.

And my implementation:

public class ItemRepository : IItemRepository
{
    private IQueryable<Item> _DataSource;
    private LynxEntities _Entities;
 
    public ItemRepository(LynxEntities entities)
    {
        _Entities = entities;
        _DataSource = _Entities.Item;
    }
 
    public ItemRepository(IQueryable<Item> dataSource)
    {
        _DataSource = dataSource;
    }
 
    Item IItemRepository.Get(int itemCodeID)
    {
        // implementation
    }
 
    List<ValidationErrorResult> IItemRepository.Save(Item item)
    {
        // implementation
    }
 
    void IItemRepository.Delete(Item item)
    {
        // implementation
    }
 
    List<ValidationErrorResult> IItemRepository.Add(Item item)
    {
        // implementation
    }
 
    List<Item> IItemRepository.Search(string name, string description, int itemsPerPage, int pageNumber)
    {
        // implementation
    }
}

I’ve removed all the implementation because it’s not relevant.  The important part is the constructors.  The first constructor is the default constructor.  It is very important with LINQ to Entities that you pass the entity object into the constructor instead of creating it.  This is because if you don’t and you get items from another repository with a different entity object then your relationships are not going to work.

The second constructor allows me to construct a list of objects with which to test in my unit testing environment.  We use MSTest and Rhino Mocks to support our testing framework.  Each of my repository classes will have a test class associated with it, and each test class will have a method to setup the data to test with.

List<Item> data = new List<Item>
{
    new Item
    {
        // Item details
    },
    new Item
    {
        // Item details
    }
};
 
ItemRepository target = new ItemRepository(data);

Allowing me to easily test my database functions without having to connect to any form of real data source.  You will run into problems when you try to run the SaveChanges methods of the entity model as when unit testing your entities object will be null.  You can just ensure that you test for null before saving changes to the data model like this:

if (_Entities != null)
{
    _Entities.SaveChanges();
}

Implementing the Repository Pattern

Once we have the repository we need to implement it.  Code examples are the best way to show this so I’ll do that.  We’re using ASP.NET MVC so our controllers define the instance of the repository.  As the controller is the master of the unit of work, we create the entity model in the controller and give it to the repositories that we create instances of.

// Constructor
public ItemController()
{
    LynxEntities entities = new LynxEntities();
    _ItemRepository = new ItemRepository(entities);
    _AnotherRepository = new AnotherRepository(entities);
 
}

Because we are using the same entity model in all the repositories in our unit of work I can load an object from my “AnotherRepository” and set it against an item pulled from my “ItemRepository” if I need to.  If they did not share the same entity model you would get an error when you tried to save changes.

In my test classes for my controllers we use Rhino Mocks to mock the interface to the repository.  Each of my test classes defines a SetupMocks method that will setup the mocks for each interface I am mocking.

private void SetupMocks(MockRepository mocks, IItemRepository items)
{
    using (mocks.Record())
    {
        // Setup the item repository
        SetupResult
            .For(items.Get(""))
            .Return(null).Repeat.AtLeastOnce();
        SetupResult
            .For(items.Get("itemA"))
            .Return(new Item
            {
                // Item Details
            }).Repeat.AtLeastOnce();
    }
}

Now I can unit test my controller just as if it were connected to the database.

The Repository Pattern is a very straight forward solution that gives you the advantages of testable code, reusable code modules and separation of concerns between the database business rules and the application business rules.  Hopefully you find it useful.

Friday 9 January 2009

Setting up a constant class

In my code I want to write Constant.Type.Value throughout  my code, well I’ve found a nice way to do this in C#.  All my constants are going sit in a single class and I can create static structures that hold the constant strings links so:

/// <summary>
/// This class holds all the constants for the Lynx application.
/// </summary>
public static class Constant
{
    /// <summary>
    /// Usage constants reference the rfUsage.Name field.
    /// </summary>
    public struct Usage
    {
        public const string Vendor = "Vendor";
        public const string Customer = "Customer";
        public const string ItemSize = "ItemSize";
        public const string Inventory = "Inventory";
    }
 
    /// <summary>
    /// Type contants reference the rfType.Name field
    /// </summary>
    public struct Type
    {
        public const string Weight = "Weight";
        public const string Thickness = "Thickness";
    }
 
    /// <summary>
    /// Unit of measure constants reference the rfUnitOnMeasure.Name field
    /// </summary>
    public struct UnitOfMeasure
    {
        public const string Grams = "Grams";
        public const string Millimeters = "Millimeters";
        public const string Box = "Box";
        public const string Bundle = "Bundle";
    }
}

And I make calls to the constants list like so:

Name = Constant.UnitOfMeasure.Grams

Tuesday 6 January 2009

Happy Holiday Season

But I didn’t get you anything, so instead you can share in the links that I check every day for entertainment, interest, news and blogging.

News

Woot.com I’m not American, but I’m always interested to see what’s going on and this site shows some really interesting deals.
eeeuser.com I love my Eee PC, this site is a fairly good source for eee news, though it’s been a bit quiet of late.
Catch Of The Day Ok so it’s mostly crappy demtel marketing crap, but occasionally there’s something really good on there.
Mobile Tech Mobile device news, a good site for info.
Google Reader All my feeds are pointed piped into google reader now.
Stack Overflow The actual link points to all the tagged items I am interested in on stack overflow.  A great site for asking and answering questions.
Giveaway Of The Day Licensed software free for download for a day.  I’ve found a couple of cool tools here that I liked, no risk installations and easy removal if they aren’t all they’re cracked up to be.
Info Synch Mobile device tech news.
New Scientist Always a good read on here, I subscribe to the RSS feed now instead of visiting the site.

Games

Aussie Nintendo I love my Wii, this is the best source of local news for Nintendo in  Australia.
Wii Fanboy International news on the Wii… argh I’m a fanboy!
Zero Punctuation If you’ve never seen these, they will make you cry.

Comics

XKCD Should be familiar to most geeks out there
Sinfest Been following this one for years, it’s fantastic.
Us the Robots The Author is pretty  slow at producing these but they’re really funny and very smart.
Dilbert Duh