Archive

Posts Tagged ‘LINQ To SQL’

LINQ To SQL - Going POCO and more……! Part 2.

September 27th, 2008 Simon Segal No comments

In part 1 of this post I made the code available for a framework that I named Golden Gate, which provided the pieces to use a POCO approach in using the LINQ To SQL OR/M along with Specifications (for dynamic querying and equality testing) and Fetching Strategies (providing flexible load options to suit the eager or lazy load requirements). What was missing in the code download was an example that utilised the DataContext classes ability to provide lazy loading or deferred loading as it terms it. The code below demonstrates how to create your POCO entities to allow for this.

//For the One to Many side of a relationship

private EntitySet<RingtailPage> _pages;

public IList<RingtailPage> Pages
{
    get { return _pages; }
    set { _pages.Assign(value); }
}

//For the Many to One side of a relationship

private EntityRef<RingtailDocument> _document;

public RingtailDocument Document
{
    get { return _document.Entity; }
    set { _document.Entity = value; }
}

Whilst the use of the EntitySet<T> and EntityRef<T> dont exactly fit the purist POCO approach, it’s a small price to pay when you consider that access to them are wrapped by an accessor mutator that exposes the Entity in question or an IList<T> where T is the entity in question. Matthew Charles explains why EntitySet<T> and EntityRef<T> are required for LINQ To SQL lazy loading.

Share/Save/Bookmark

Categories: LINQ To SQL, ORM, POCO Tags: , ,

POCO Custom Multifile Assembly and ReSharper

September 25th, 2008 Simon Segal No comments

I recently compiled all the libraries from my most recent post on LINQ To SQL, into a Multifile Assembly so people could play with the bits without having to load up the projects that make up the POCO Framework which contains the Repository / Specification and Fetching Strategy libraries in it’s VS.Net solution.

The trick in creating a custom multifile assembly is to take all the files from the libraries that you wish to blend into one assembly, compile them into netmodules and then combine them all with the Assembly Linker otherwise know as al.exe. In my case the modules were as below:

metmodules

and the last command I had to execute on the command line was:

al <module name> <module name> … /main:<method name> /out:<file name> /target:<assembly file type>

where the module names were from my list above.

One thing to watch out for if your a ReSharper user: the multifile assembly (your DLL compiled from the netmodules) may not be recognised correctly by intellisense in VS.Net 2008 and may report that it cannot resolve symbols. I didn’t dig into the cause of this problem however turning ReSharper off will stop the warning and code window highlighting but the problem does not stop VS.Net successfully building and executing your code nonetheless.

multifileIntellisenseProb

As you can see, the ‘Repository’ type is not having intellisense resolve it correctly and it is showing up in RED! But let me re-iterate that this will not preclude your code from building and running in VS.Net 2008 and turning off ReSharper will remove the intellisense problem altogether.

ggateReflector

The multifile assembly for my previous posts code can be found here and if you browse it in Reflector you can see that it incorporates all the namespaces and code from the multiple projects in the LINQ To SQL going POCO solution.

Share/Save/Bookmark

Categories: Dotnet, LINQ To SQL, ORM Tags: , ,

LINQ To SQL - Going POCO and more…..!

September 16th, 2008 Simon Segal 16 comments

Ok so I have posted on this a few times and rather than keep it waiting for the code to mature into anything deeper than more than what it is, I have decided to get the example working code up for download now and not keep it hanging around for too long.

A lot of people are expressing a lot of interest in the how to leverage LINQ To SQL using POCO (Plain Old CLR Objects) and this generic Repository approach utilises POCO’s along with Specifications and Fetching strategies (an nHibernate concept). The Repository<T> is designed for use out of the box however it can also be extended. I should make it clear that the code is not yet entirely complete and certainly I wouldn’t yet be releasing to my own team as ratified framework plumbing, nonetheless I am keen to get it posted to finish the discussion I started in previous posts.

The Cut and Thrust

The idea of the generic repository began as an extension of the ideas expressed by Mike Hadlow in his article here which are derived from Ayende’s work here.

public interface IRepository<T>
{
    void Save(T domainObject);
    void SaveAll(IList<T> domainObjects);
    void SaveCompared(T modifiedDomainObject, T originalDomainObject);
    void SaveNew(T domainObject);
    void Delete(T domainObject);
    void Delete(ISpecification<T> spec);
    void Delete(T domainObject, Expression<Func<T, bool>> children);
    void Delete(Expression<Func<T, bool>> predicate);
    IList<T> All();
    IList<T> All(ISpecification<T> spec);
    IList<T> All<TRole>(ISpecification<T> spec);
    IList<T> All(ISpecification<T> spec, IFetchingStrategy strategy);
    T First();
    T First(ISpecification<T> spec);
    T First<TRole>(ISpecification<T> spec);
    T First(ISpecification<T> spec, IFetchingStrategy strategy);
    T Unique(ISpecification<T> spec);
    T Unique<TRole>(ISpecification<T> spec);
    T Unique(ISpecification<T> spec, IFetchingStrategy strategy);
    DataContext UnitOfWork { get; }
}

Were the code really begins to diverge from Mike’s example is where you can see the dependencies that the IRepository has to the ISpecification and IFetchingStrategy, both of which I have posted previously about. ISpecification implements the Specification pattern popularised by Eric Evans in Domain Driven design and our ISpecification provides the ability to test for object equality by matching the specification ; the EvalPredicate is specifically targeted to enabling dynamic expression building and giving us dynamic querying in the process. The design of ISpecification is all but entirely based on Dave Laribee’s Sexy Specifications post, the addition of the EvalPredicate provides the dynamic query functionality.

public interface ISpecification<T>
{
    Expression<Func<T, bool>> EvalPredicate { get; }
    bool Matches(T entity);
}

The Fetching Strategy approach enables targeting code for runtime lazy or eager loading strategies and borrows from Udi’s approach with NHibernate and NServiceBus which is to allow for pluggable code that has no compile time coupling to the consumer code, that is, you can literally write Fetching Strategies and drop them in a folder location and if you call the write method in the Repository that accepts a generic paramater as a role or <TRole> [as a hint] then your strategy will be nice enough to load for you.

public interface IFetchingStrategy
{
    DataLoadOptions LoadOptions { get; }
}

/// <summary>
/// Marker Interface
/// </summary>
/// <typeparam name="TRole">
/// Specification of a role for 
/// dyanmic runtime type lookup
/// </typeparam>
public interface IFetchingStrategy<TRole> : IFetchingStrategy{ }

Some DDD’ers very much like to be very explicit with their Repositories in particular in defining the behaviours, such as GetByProductCatalog() for example. The generic approach is taken to reduce the amount of code written in the case where you may need many small repositories with little or no specific behaviours. Having said that you are still free to extend the generic repository and specialise that class.

Here are some samples that exemplify how to use the code to query your database.

public void SimpleRepositoryFetchingStrategyTest()
{
    Specification<Customer> simonsCoSpec =
        new Specification<Customer>(c => c.Country == "Germany");

    DataContext ctx = GetContext();

    Repository<Customer> customerRepository =
        new Repository<Customer>(ctx);

    CustomerLoyaltyDiscountFetchingStrategy strategy =
        new CustomerLoyaltyDiscountFetchingStrategy();

    var custs = customerRepository.All(simonsCoSpec, strategy);

    foreach (var cust in custs)
    {
        cust.LoyaltyDiscount();
        Console.WriteLine("The Name of the Customer from " +
            "Germany is {0}", cust.CompanyName);
        foreach (var order in cust.Orders)
        {
            Console.WriteLine("\tOrder Number {0}", order.OrderID);
            foreach (var orderLine in order.OrderLines)
            {
                Console.WriteLine("\t\tProduct ID {0} Amount {1}",
                       orderLine.ProductID,
                       (orderLine.Quantity * orderLine.UnitPrice));
            }
        }
    }
}

As you can see our CustomerLoyaltyDiscountFetchingStrategy defines a lazy loading approach. It should be noted that Fetching Strategies can also include the use of the AssociateWith method of the DataLoadOptions class which is used to further refine the filtering capabilities of an IFetchingStrategy.

Another upside is that I can write unit tests that do not rely on my database and consequently slow down my testing automation. Ian Cooper demonstrated something similar and this a well known design goal amongst those that practice Domain Driven Design. You can see from the code example below, I am able to supply my repository with in memory objects and mock behaviours without any connection to the database.

[Test(Description="Tests the All method of the " +
                  "Repository for accurate data Retrieval")]
public void SingleExpectationFromAllMethod()
{
    var mockRep = new Mock<IRepository<Customer>>();

    mockRep.Expect(r => r.All()).Returns(() => new List<Customer>()
    {
       new Customer()
           {
               CustomerID = "SIMONS"
           }
    });

    Assert.AreEqual(mockRep.Object.All().First().CustomerID, "SIMONS");
    mockRep.VerifyAll();
}

So that’s it for this topic. Looks for the moment that I will use L2S where appropriate and although the Entity Framework is still pretty clunky and lacking purity in the POCO pursuits, I expect Microsoft to get it right eventually. You can download the entire code here which also includes Kris’ DebuggerWriter for printing SQL statements to the debug window from the LINQ To SQL DataContext and a slightly modified version of the ubiquitous Northwind database.

Share/Save/Bookmark

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