tags:

views:

150

answers:

2

Simplified repeated code for each entity type is

public IList<entity1> GetEntity1(.. query params ..)
{
    IQueryable<entity1> query = context.entity1;

    query = from refDataType in query
            where refDataType.Id > 0
            select refDataType;
    .
    . plus more changes to query same for each entity
    .

    return query.ToList();
}

I wanted to create a generic function that creates the query, but not sure how to go about it?

ie in the following snippet, How do I code for ReturnAGenericQuery?

 public IList<entity1> GetEntity1(.. query params ..)
{
    IQueryable<entity1> query = context.entity1;    
    query = ReturnAGenericQuery of type entity1
    return query.ToList();
}

public IList<entity2> GetEntity2(.. query params ..)
{
    IQueryable<entity2> query = context.entity2;    
    query = ReturnAGenericQuery of type entity2
    return query.ToList();
}

private IQueryable<T> ReturnAGenericQuery<T> ()
{
    return IQueryable of entity1 or entity2
}
+3  A: 

Your example is a little vague, but it looks like you need something along the lines of:

private IQueryable<T> ReturnAGenericQuery<T>(IQueryable<T> source)
    where T : SomeBaseTypeForAllYourEntities
{
    IQueryable<T> result =
        from refDataType in source
        where refDataType.Id > 0
        select refDataType;

    // Other stuff here

    return result;
}

public IList<Entity1> GetEntity1( ... )
{
    return ReturnAGenericQuery(context.entity1).ToList();
}

The reason you need the 'where T :' clause is because T needs to be a type that has a property 'Id' for your LINQ where-clause to work ... so you'd need to derive Entity1 and Entity2 from a base class that defines that property. If you need any other properties for the 'other stuff' these will need to be added to the base class too.

Addendum:
If context.entity1 (whatever collection that refers to) is not an IQueryable<entity1>, then you may need to use context.entity1.AsQueryable() instead.

Originally my query was wrong, it was supposed to query from refDataType in source rather than in result... duh.

Provided you have the right kind of inheritance structure (see below), this compiles fine.

public class SomeBaseTypeForAllYourEntities
{
    public int Id { get; set; }
}

sealed public class Entity1 : SomeBaseTypeForAllYourEntities
{
    ... other properties, etc. ...
}
jerryjvl
This won't compile (even if you give 'source' and 'query' the same name) until you give the method a 2nd type parameter. 'result' is IQueryable<typeof(refDataType)> which is not the same as the entity type T.
Richard Berg
There was an 'AsQueryable()' missing, and there was a typo in my query, but other than that this compiles just fine... added some more detail to be absolutely clear.
jerryjvl
+1  A: 

You need an interface.

private IQueryable<T, R> ReturnAGenericQuery<T> (T entity) where T : IQueryable, IHasRefDataType
{
    return from DataType refDataType in entity
           where refDataType.Id > 0
           select refDataType;
}

struct DataType
{
    public int Id;
}

public interface IHasRefDataType
{
    DataType refDataType;
}
Richard Berg
Is IHasRefDataType a lolcats interface? ;)
Robert Harvey
@Robert: No, that'd be IHazRefDataType, surely?
jerryjvl
Yes, hope it brightened your day ;)
Richard Berg