# Sunday, August 24, 2008

There are currently two approaches when using L2S. Either adding attributes to classes to denote columns, or creating an external XML mapping definition. Neither of these is great. Attributes mix non domain concerns, namely database schema, into domain objects. XML mapping needs to be kept in sync with the classes it describes. During the early stages of a new project, the structure of classes can vary and morph over time. So manual mapping is annoying.

My suggestion is to create a "convention-based" mapping. Where you can define POCOs and then have reflection to build the mapping, based on some simple naming conventions. This mapping can then be used by a DataContext and a database created from it. (Note that I am only considering green field developments, where we are working "code-first".)

The conventions I have thought about so far include:

  • A property named "Id" will be the primary key.
  • If Id is an int then make it auto incrementing.
  • All primitive, string and DateTime properties are columns.
  • All properties having the type of another entity in the DataContext are associations.
  • All properties of type EntityRef<T> are associations.
  • There must be a foreign key Id property defined for associations.
  • Any property with subtype a of IList<T> is an association.

One-to-many associations need to be a bit smart with their names. Consider:

class Customer {
  public Employee ReferringEmployee { get; set; }
}
class Employee {
  public List<Customer> ReferredCustomers { get; set; }
}

The mapping needs to understand the "ing" and "ed" relation. Also, we'll perhaps need support for TechSupportEmployee <--> TechSupportedCustomers.

The conventions should follow the usual rules of English grammar. I hope, therefore, that they do not interfere with the universal language discovered by domain driven design.

As a project begins to settle down, there will be requirements that the convention mapping doesn't support. Rather than having to switch to full manual XML mapping, perhaps an augmentation layer could applied. This could describe specific cases of the mapping that are different. For example, a certain primary key column using GUIDs instead of integers.

c# | linq | linq-to-sql | orm
Sunday, August 24, 2008 11:09:43 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, October 02, 2007

Has anyone looked into an extension method on the .NET 3.5 Expression class that returns a JavaScript method? This could then be sent to the client web browser.

So you could then write validation logic in C# and run it in the browser as JavaScript!

.net | c# | linq | thinking
Tuesday, October 02, 2007 9:39:56 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 
# Thursday, September 27, 2007

Imagine we have a set of complex expressions. A subset of these need to be evaluated at runtime, depending on some state external to the program (e.g. user input). If these subsets are not distinct from each other then the code will likely become messy and unstructured.

What we would like to so is define all the expressions first and then pick and choose those required. This would of course involve evaluating all of the them. This wasteful of time if only a few are required.

Enter lazy evaluation! From my rather limited exposure to Haskell, I hear that lazy evaluation is all the rage. :)

Using lambdas in C# 3.0 we can create code like this:

long x = 42;
var lx = Lazy.Eval(() => x * x * x * x * x * x);
if (some_boolean_expression)
{
  UseNumber(lx);
}

where UseNumber is some function that takes a "long" as input.

Now this example is over-simplified, but it shows the mechanics. We use a call to Lazy.Eval to return a wrapper around the lambda. So at that point we have not calculated the expensive expression. Later in the program the variable "lx" is used. lx is of type Lazy<long> and there exists an implicit cast from Lazy<long> to long. At this point the original expression is evaluated and saved by the lazy wrapper. So next time the value is required the cached value is returned.

Here is the Lazy<T> class:

public class Lazy<T>
{      
    bool _gotValue;
    T _value;
    Func<T> _expr;

    public Lazy(Func<T> expr)
    {
        _expr = expr;
    }

    public T Value
    {
        get
        {
            if (!_gotValue)
            {
                _value = _expr();
                _gotValue = true;
            }
            return _value;
        }
    }

    public static implicit operator T(Lazy<T> l)
    {
        return l.Value;
    }
}

And to allow the C# 3.0 compiler to infer types for us, we use a separate Lazy class:

public class Lazy
{
    public static Lazy<T> Eval<T>(Func<T> expr)
    {
        return new Lazy<T>(expr);
    }
}

Whilst lazy evaluation may not be useful in everyday programming, this example does show some of what can be achieved with lambdas in C# 3.0.

.net | c# | linq | programming
Thursday, September 27, 2007 11:56:51 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, September 05, 2007

When writing assertions it is annoying to write a string that basically mirrors what the code your testing says. For example:

Debug.Assert(input != null, "input != null");

Similar statements appear when unit testing with tools like NUnit.

With Linq it is now possible to avoid this by using expression trees. The basic idea is to take a boolean assertion function as an expression tree so that we can call ToString() to get the message for the assert.

void Assert<T>(T obj, Expression<Func<T, bool>> test)
{
  System.Diagnostics.Debug.Assert(test.Compile().Invoke(obj), test.ToString());
}

This is then called like:

Assert(input, i => i != null);

Given this idea, we can play with the syntax a bit. Using an extension method:

static class Exts
{
    public static void MustSatisfy<T>(this T obj, Expression<Func<T, bool>> test)
    {
        Debug.Assert(test.Compile().Invoke(obj), test.ToString());
    }
}

We then have:

input.MustSatisfy(i => i != null)

Another syntax option would be something like:

Assert.That(foo).Satisfies(
  i => i > 0,
  i => i < 100);

Where we are now passing an array of assertions (using a params arg in the Satisfies method).

.net | c# | linq | programming | syntax
Wednesday, September 05, 2007 12:46:23 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [3]  |