score:1

Accepted answer

I'm pretty sure you can't make the one compiled-query span multiple tables (if that is what you mean); how would it know where to look? EF supports something like this with inheritance (and multiple tables), but even with inheritance LINQ-to-SQL only supports single-table discriminated inheritance.

The heart of this question is largely identical to this one from earlier today. The tricky bit is the primary key, since that is hard to define abstractly. The rest is just GetTable<T> (with LINQ-to-SQL at least).

You don't need a superclass in this case - just a way to get the primary key. Fortunately, I seem to recall that LINQ-to-SQL offers a way to do this (without needing to use the attributes, which is not a pre-req of LINQ-to-SQL); the following doesn't pre-compile (and is untested), but should be fairly close:

(update fixed and tested)

Usage first:

Foo foo = ctx.Get<Foo>(fooid);
Bar bar = ctx.Get<Bar>(barid);

code:

    public static TItem Get<TItem, TKey>(
        this DataContext ctx, TKey key)
        where TItem : class
    {
        var table = ctx.GetTable<TItem>();
        var primaryKey = ctx.Mapping.GetMetaType(typeof(TItem))
                .DataMembers.Where(
            member => member.IsPrimaryKey).Single().Member.Name;

        var item = Expression.Parameter(typeof(TItem), "item");
        var lambda = Expression.Lambda<Func<TItem, bool>>(
            Expression.Equal(
                Expression.PropertyOrField(item, primaryKey),
                Expression.Constant(key, typeof(TKey))),
                item);
        return table.Single(lambda);
    }
    public static TItem Get<TItem>( // common case
        this DataContext ctx, int key)
        where TItem : class
    {
        return Get<TItem, int>(ctx, key);
    }
    public static TItem Get<TItem>( // common case
       this DataContext ctx, string key)
       where TItem : class
    {
        return Get<TItem, string>(ctx, key);
    }

I'll see if I can find a way to pre-compile it...

score:2

Instead of doing that, derive all your entities from a base entity that has common properties in your entities (like Id). Implementing these layer with POCO will help you.


Related Articles