views:

56

answers:

1

I have 3 methods that are almost exactly identical:

protected DetachedCriteria GetAvailableFundIdsPerDataUniverse()
{
    return GetAvailableIdsPerDataUniverse()
        .SetProjection(LambdaProjection.Property<Fund>(f => f.Id));
}

protected DetachedCriteria GetAvailableCompanyIdsPerDataUniverse()
{
    return GetAvailableIdsPerDataUniverse()
        .SetProjection(LambdaProjection.Property<Fund>(f => f.Company.Id));
}

protected DetachedCriteria GetAvailableCategoryIdsPerDataUniverse()
{
    return GetAvailableIdsPerDataUniverse()
        .SetProjection(LambdaProjection.Property<Fund>(f => f.Category.Id));
}

where GetAvailableIdsPerDataUniverse() is defined as:

protected DetachedCriteria GetAvailableIdsPerDataUniverse()
{
    return DetachedCriteria.For<Fund>()
        .SetFetchMode<Fund>(f => f.ShareClasses, FetchMode.Join)
        .CreateCriteria<Fund>(f => f.ShareClasses)
        .Add(LambdaSubquery.Property<ShareClass>(x => x.Id).In(GetAvailableShareClassIdsPerDataUniverse()))
        .Add<ShareClass>(f => f.ExcludeFromFT == false);
}

For each method, the only difference is the expression that's used to select the data, i.e.

f => f.Id, f => f.Company.Id and f => f.Category.Id

Could somebody please tell me if it's possible to pass that those differences into GetAvailableIdsPerDataUniverse() as a variable so I can have only 1 method instead of having 4?

+2  A: 

typing directly in browser, so may not contain errors

protected DetachedCriteria GetAvailableIdsPerDataUniverse(Expression<Fund, int> e)
{
    return DetachedCriteria.For<Fund>()
        .SetFetchMode<Fund>(f => f.ShareClasses, FetchMode.Join)
        .CreateCriteria<Fund>(f => f.ShareClasses)
        .Add(LambdaSubquery.Property<ShareClass>(x => x.Id).In(GetAvailableShareClassIdsPerDataUniverse()))
        .Add<ShareClass>(f => f.ExcludeFromFT == false).
        .SetProjection(LambdaProjection.Property<Fund>(e));
}

GetAvailableIdsPerDataUniverse(e => e.Category.Id)
//...

Edit I've checked documentation of NHibernate.LambdaExtensions, type of LambdaProjection.Property is

public static PropertyProjection Property<T>(Expression<Func<T, object>> expression)

So parameter type should be

System.Linq.Expressions.Expression<Func<Fund, object>>
desco
Thanks @desco, but this gives the error `The non-generic type 'NHibernate.Criterion.Expression' cannot be used with type arguments`. Have you seen this before? Do you know how I can resolve that?
DaveDev
Use full name of type (System.Linq.Expressions.Expression<Func<Fund, int>> e)
desco
Thanks desco, I actually figured the `object` instead of `int` bit myself a few minutes ago and it all works perfectly. I'd never have gotten that far without your help though. This is going to help me reduce the amount of code I need to write exponentially!
DaveDev