Archive

Archive for February, 2009

Losing the argument………

February 13th, 2009 Simon Segal No comments

I just finished listening to a software development podcast and towards the end of  the panel discussion it got rather heated, or perhaps it just sounded that way on an MP3 and you just had to be there? At any rate - one of the panel members (seemed) to lose it a bit and a started raising his voice and getting his back up over what he seemed to think was an unfair statement or sentiment regarding loosing_itone of the technologies under discussion. Anyway, this reminded me of something I want to try and be vigilant about and observe and that is not to be the guy in the corner losing his cool, cause the moment you do that you have lost the argument, your credibility is diminished and respect from your fellow debaters and audience will be lost. The software development business is littered with opportunity to shoot yourself in your zealot foot but try to resist the temptation, I know I will.

Share/Save/Bookmark

Categories: Career Tags:

The Entity Framework and a unified Lazy and Eager loading framework.

February 11th, 2009 Simon Segal 13 comments

I am in the middle of spiking a solution that aims to unify an approach to lazy and eager loading with the Entity Framework. I was ready to give up on the idea a while back but I am a stubborn PITA. It has been my goal for a while to try get Specifications, Repositories and (finally) Fetching Strategies bundled into a single approach for the Entity Framework. What I want to be able to do is write code like this:

public void Multi_Level_Mixed_Hierarchy_With_Persisting_Test()
{
    EntitiesRepository<Customer, NorthwindEntities> repos =
        new EntitiesRepository<Customer,
            NorthwindEntities>(new NorthwindEntities());

    Specification<Customer> german_cust_spec =
        new Specification<Customer>(c => c.CustomerID == “ALFKI”);

    var german_custs = repos.AllAsIList(“Customers”, german_cust_spec, new
                        MultiLevelMixedStrategy());

    foreach (var cust in german_custs)
    {
        cust.Country = “Italy”;
        Console.WriteLine(“The Customer Name is {0}”, cust.CompanyName);
        foreach (var order in cust.Orders)
        {
            order.ShipName = “The big boat”;
            Console.WriteLine(“\tThe Order ID is : {0}”, order.OrderID);
            foreach (var orderline in order.Order_Details)
            {
                orderline.Discount = 0.13f;
                Console.WriteLine(“\t\tThe value ordered for ” +
		    “Product ID {0} is {1}”,
                    orderline.Product.ProductID,
                    orderline.UnitPrice * orderline.Quantity);
            }
        }
    }

    repos.Session.SaveChanges();
}

The Repository and the Specification aspects to this unified approach have previously been developed and documented but the missing piece that has been outstanding is the Fetching Strategy. You can see above in the call to the repository .AllAsIList() method, that the third argument is the Fetching Strategy of which I speak.

public interface IFetchingStrategy
{
    IList<FetchingIntention> Intentions { get; }
}

public interface IFetchingStrategy<TRole> : IFetchingStrategy { }

And the implementation is:

public class MultiLevelMixedStrategy :
    IFetchingStrategy
{
    private readonly IList<FetchingIntention> _intentions =
        new List<FetchingIntention>();

    public MultiLevelMixedStrategy()
    {
        this.Intentions.Add(new FetchingIntention(“Orders”,
                                FetchMode.Eager));
        this.Intentions.Add(new FetchingIntention(“Orders.Order_Details”,
                                FetchMode.Eager));
        this.Intentions.Add(new FetchingIntention(“Product”,
                                FetchMode.Lazy));
    }

    public IList<FetchingIntention> Intentions
    {
        get { return _intentions; }
    }
}

Where the Entity Model looks like this:

ef_with_box_and_dice

So far the results look promising. I will have more to say on this shortly and with a bit of luck will be releasing the code which rounds out the triad of a Repository, dynamic querying capability via Specifications and Fetching Strategies for a unified approach for lazy and eager loading that does NOT require you ever explicitly call the .Includes(), Load() or IsLoaded methods and property on the EntityCollection<T>, EntityReference<T> or ObjectQuery<T> objects.

Share/Save/Bookmark

IronRuby and the Entity Framework - Part 1.

February 8th, 2009 Simon Segal 2 comments

First of all let’s be absolutely clear - you get no Entity Model Designer, so we wont be building Entities in IronRuby. What we will be doing is building our Entity Model inside a C# library project and we will consume our model from IronRuby code. Admittedly I would expect support for the aforementioned design experience eventually but for now we can consume the Entity Framework in IronRuby in this way.

Some house keeping first! If you want to move quickly through this code and enjoy using Visual Studio then I suggest downloading the free Alpha version of RubyInSteel (for IronRuby only) here.

Given the following (ubiquitous) Northwind Entity Model (built in a C# library project).

ironruby_entity_model

with a ‘partial class’ augmentation on the ObjectContext as follows:

public partial class NorthwindEntities :
                     global::System.Data.Objects.ObjectContext
{
    public List<Customers> GetAllCustomers()
    {
        return this.Customers.ToList();
    }
}

We can write the following IronRuby code:

require ‘System.Windows.Forms, Version=2.0.0.0, ‘ +
    ‘Culture=neutral, PublicKeyToken=b77a5c561934e089′
require ‘D:/simon.segal/Local Working/Org.Techavalanche.IronEntities’ +
    ‘/Org.Techavalanche.EntityLibsForRuby/bin/Debug’ +
    ‘/Org.Techavalanche.EntityLibsForRuby.dll’
require ‘System.Data, Version=2.0.0.0, ‘ +
    ‘Culture=neutral, PublicKeyToken=b77a5c561934e089′
require ‘System.Data.DataSetExtensions, ‘ +
    ‘Version=3.5.0.0, Culture=neutral, ‘ +
    ‘PublicKeyToken=b77a5c561934e089′
require ‘System.Data.Entity, Version=3.5.0.0, ‘ +
    ‘Culture=neutral, PublicKeyToken=b77a5c561934e089′
require ‘System.Core, Version=3.5.0.0, ‘ +
    ‘Culture=neutral, PublicKeyToken=b77a5c561934e089′

providerName = “System.Data.SqlClient”;
serverName = “boomer”;
databaseName = “Northwind”;

#Initialize the connection string builder for the
#underlying provider.
sqlBuilder = System::Data::SqlClient::
                SqlConnectionStringBuilder.new

#Set the data source properties
sqlBuilder.DataSource = serverName;
sqlBuilder.InitialCatalog = databaseName;
sqlBuilder.IntegratedSecurity = true;

#//Build up the provider string part of the connection string
providerString =
    sqlBuilder.ToString();

#Initialize an EntityConnectionStringBuilder and set its provider name
entityBuilder = System::Data::EntityClient::
    EntityConnectionStringBuilder.new
entityBuilder.Provider = providerName;

#Sets the part of the connection string that is provider specific
entityBuilder.ProviderConnectionString = providerString;

#Points to the location of the model schema files
entityBuilder.Metadata =
    “res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl”

#get the entire connection string
con = entityBuilder.ToString()

#new up an ObjectContext from the C# library
session = Org::Techavalanche::
        EntityLibsForRuby::NorthwindEntities.new(con)

#ask for all the customers
custs = session.GetAllCustomers

#print out the customer company name
for cust in custs
    puts cust.CompanyName
end

Currently the implementation of IronRuby does not fully work with LINQ and trying to call the extension methods directly on an ObjectContext<T> yields errors. You can however build your own data access layer in another language such as C# or VB.Net and call into that library as demonstrated in this post. I have made the code available here and will continue to follow the development of IronRuby and how it fits into the scheme of things with Data Access as it progresses towards release.

Share/Save/Bookmark

Creative Commons Attribution-ShareAlike 2.5 Australia
Creative Commons Attribution-ShareAlike 2.5 Australia