Při vývoji aplikace, která obsahuje docela hodně tabulek jsem se dostal do situace, kdy jsem potřeboval vrátit konkrétní položku podle ID. Nechtělo se mi ovšem pro každou z X tříd psát metodu, která bude dělat pořád to stejné.

Vytvořil jsem si tedy generickou metodu GetObjectByID

public static T GetObjectByID<T>(int id) where T : class
{
    if (id < 0)
        throw new ArgumentException("id");

    Type objectType = typeof(T);
    Type columnType = typeof (ColumnAttribute);

    // ziskam si sloupec PK
    PropertyInfo pkProperty = objectType.GetProperties().Where(
        prop => prop.GetCustomAttributes(typeof (ColumnAttribute), false).First() != null &&
                ((ColumnAttribute) prop.GetCustomAttributes(typeof (ColumnAttribute), false).First()).
                    IsPrimaryKey
        ).First();

    // vytvorim si vyraz
    ParameterExpression parameter = ParameterExpression.Parameter(objectType, "CurentTable");
    var predicate = Expression.Lambda<Func<T, bool>>(Expression.Equal(
                        Expression.Property(parameter, objectType.GetProperty(pkProperty.Name)),
                        Expression.Constant(id)),
                    parameter);

    return Db.GetTable<T>().Where(predicate).FirstOrDefault();
}

Jelikož potřebuju hledat podle ID, tak si z konkrétního objektu musím najít takovou vlastnost, která je označena atributem CollumnAttribute a zárověn je i primární klíč. Jakmile mám nalezenou konkrétní vlastnost, tak si vytvořím predikát, který obsahuje výraz pro porovnání mojí nalezené vlastnost (PK) s id, které je parametrem mojí metody.

Na základě generického typu T si získám tabulku a na konkrétní tabulce zavolám extensní metodu Where, kde jí jako parametr předám ten můj predikát. Nyní už jen vrátím výsledek a je to. Myslím si, že to ušetří docela dost času :-)

Ještě zde přidám ukázku, jak provádět hledání podle více ID, ale to už je jednodušší

public static IQueryable<T> GetObjectsByID<T>(IEnumerable<int> ids) where T : class 
{
    List<T> result = new List<T>();

    foreach (var id in ids)
    {
        result.Add(GetObjectByID<T>(id));
    }
    return result.AsQueryable();
}

Lukáš