0

I've got a few tables that all have the same column domainID which basically just controls what data gets displayed on which website, as they share a database.

So when I go to databind a table to a control I would need to create a large switch to handle the different LINQ queries. I would like to create a utility method which takes the table type as a parameter and then return a where clause based on a column in passed table.

public static IEnumerable<T> ExecuteInContext<T>(
               IQueryable<T> src)
        {
             int domain = 1;//hard coded for example

             return src.Where(x => x.DomainID == domain);//Won't work, has to be a way to do this.            
        }

I'm stuck on the return code. You can't simply construct a where clause like I currently am because it doesn't know what table i'm talking about.

I'm trying to call that first method like this:

using (DataClasses1DataContext db = new DataClasses1DataContext())
        {

            var q = Utility.ExecuteInContext(db.GetTable<item>());

            Repeater1.DataSource = q;
            Repeater1.DataBind();
        }

I hope this explains what I'm trying to do.

Edit: BrokenGlass's answer solved my problem. I would like to add that you need to open up your .dbml.cs file and extend the table/class with your interface. I also wanted to point out that the project wouldn't build if my column was nullable, it said it wasn't the same return type as my interface.

4 Answers 4

3

You have to restrict your T to a class that has a property of DomainID - you can add these interface implementations in partial classes that extend your data model.

public interface IFoo
{
    int DomainId { get; set; }
}
..

public static IQueryable<T> ExecuteInContext<T>(IQueryable<T> src) where T: IFoo
{
  int domain = 1;//hard coded for example
  return src.Where(x => x.DomainID == domain);
}
Sign up to request clarification or add additional context in comments.

4 Comments

When I try to call this method and set the parameter as my item table it says there is no explicit reference conversion from item to utility.IFoo
does your item table class implement IFoo ? This is necessary for this to work. You might have to add this in a partial class, I work with Linq to Entities - hopefully the same is possible in Linq to SQL, if not then ignore this answer
I'm not sure how to do that. What I currently have is the second code block in my question.
I got it to work. I created a new partial class for each table class that inherits IFoo. Thanks for the base code.
2
Expression pe = Expression.Parameter(typeof(T));
Expression prope = Expression.Property(pe, "DomainID");
Expression ce = Expression.Equals(prope, 
    Expression.Constant((int)1);

Expression<Func<T,bool>> exp =
Expression.Lambda<Func<T,bool>>(
    ce, pe);

return query.Where(exp);

2 Comments

this looks scary but interesting - so this approach would work regardless of what type T is if it has a property DomainID ?
Yes, if you use reflector, this is what exactly compiler does.
0

You should be able to cast your generic parameter to the intended type...

public static IEnumerable<T> ExecuteInContext<T>(IQueryable<T> src)
{
    int domain = 1;//hard coded for example

    return src.Where(x => ((T)x).DomainID == domain);
}

But you realize you've created a generic method that assumes its type parameter will always expose a specific property? If you're going to do that, you should apply a generic type constraint such that T is always derived from a type that has that property...

For example:

public static IEnumerable<T> ExecuteInContext<T>(IQueryable<T> src) where T : IMyDomainObject

2 Comments

The queries that will be called this method will always have a table which contains the domainID column, if that's what you mean.
It doesn't allow me to cast the parameter to the intended type.
0

I'm not sure if I understand what you mean, but maybe you want to add a where clause:

public static IEnumerable<T> ExecuteInContext<T>(IQueryable<T> src)     

     where T: MyType //MyType exposing your DomainId   
    {             
       int domain = 1;//hard coded for example            
        return src.Where(x => x.DomainID == domain);//Won't work, has to be a way to do this.                    
    }

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.