views:

65

answers:

2

I have a class with a title in it. I have a property that returns that title adjusted a bit. If I do Linq to Sql queries off the adjusted title property I get the "not supported" exception. If I do the same thing the property does directly in the linq query it works. Any ideas on how I can make the property work in Linq to Sql?

Here is the property

public string SeoName
{
 get { return Name.ToLower().Replace(" ", "").Replace("&", "and"); }
}

Here is the query that doesn't work (What I would like to be able to do).

var series = from s in videoRepo.GetShows()
    where s.Topic.SeoName.Equals(topicSeoName)
    select s;

Here is a query that does the same thing and works

var series = from s in videoRepo.GetShows()
   where s.Topic.Name.ToLower().Replace(" ", "")
   .Replace("&", "and").Equals(topicSeoName)
   select s;

How can I structure the top property to work with the first linq query?

MY FINAL ANSWER

Added an expression that evaluated what I was looking for

public static Expression<Func<Show, bool>> 
  TopicSeoNameEquals(string name)
 {
  return t => t.Topic.Name.ToLower().
   Replace(" ", "").Replace("&", "").Equals(name);
 }

Then, I just called it a bit differently in the linq query

var test = Show.TopicSeoNameEquals(topicSeoName);

var series = from s in videoRepo.GetShows().Where(test)
   select s;
+2  A: 

Basically you can't. LINQ to SQL has no way to "look inside" the SeoName property and translate it to SQL. However, when you write what appears to be the same code inline in the LINQ to SQL query, the compiler builds it in a way that LINQ to SQL can "look inside." It creates an expression tree -- an abstract description of the sequence of operations in the query -- rather than compiling the code down to MSIL.

You can work around this by creating an Expression that does the same job as SeoName, but you still end up duplicating the SeoName code in order to get C# to compile one copy as a callable MSIL method and the other as an expression tree. (Though you can work around this by having your SeoName property work by compiling the expression tree at run time: this gets around the duplication at the expense of some performance and looking a bit strange.)

itowlson
I used your idea to come up with the final answer above.
Matthew Kruskamp
+2  A: 

Have a look at LinqKit- it's got some stuff for making one expression call another, etc. I use the PredicateBuilder a ton- great stuff.

nitzmahone
I created my answer sort-of based off the items in the link. I didn't end up using the LinqKit to do it though. Thank you for the link as it provided some good information.
Matthew Kruskamp