Accepted answer

I guess thinking more about it, it is somewhat of a stupid question. I was hoping to be able to use the cleaner query:

var query = from b in DataContext.B 
            select b;

And apply this to it:

x => x.A.Name == "Test"

Without having to have the duplicate this predicate that I use when starting the query on the A table:

x => x.Name == "Test"

So I suppose the solution is to "reverse" the query by starting on the A table, like so:

var query = from a in DataContext.A
            join b in B on a equals b.A
            select b;

query = query.Where(FilterPredicate());

I was thinking it may rewrite the queries inefficiently, but that doesn't seem to be the case.


You can do this by defining an interface over A and B.

public interface IHasName // contrived, I know
    string Name {get;}

LINQ-To-SQL classes are partial, so in your part of the partial class definition, you can add the interface like so:

public partial class A : IHasName {}
public partial class B : IHasName {}

As you see, no implementation should be needed since the Name property is implemented in the Linq-To-Sql generated part.

Now constrain your predicate to types implementing the IHasName interface, and you're all set:

private Expression<Func<T, bool>> FilterPredicate(string name) where T : IHasName
    return x => x.Name == name;

you should now even be able to define an extension method on IQueryable like so:

public static T GetByName<T>(this IQueryable<T> queryable, 
                             string name) where T : IHasName
    return queryable.Where(FilterPredicate(name)).SingleOrDefault();

Small caveat: of course, the property in the interface ('Name') must exactly match the property name in the implementing classes. Suppose you have a class C with property 'MyName'. You might be tempted to implement the IHasName interface like so:

public partial class C : IHasName
    public string Name {return MyName;} 

This will of course not work, as the Linq-To-Sql expression parser will use 'Name' instead of the actual property 'MyName', so it won't be able to map this expression to valid SQL.

Related Query

More Query from same tag