2

In my DB I have tables who have an attribute int DeleteState. I want a generic method to query those tables. In other words a method who does this: Context.Table.Where(x => x.DeleteState == 0).

I thought I could do this:

public static class Extensions
{
  public static IQueryable<T> Exists<T>(this IQueryable<T> qry) where T : IDeletable
  {
    return qry.Where(x => x.DeleteState == 0);
  }
}

Where IDeletable is this:

public interface IDeletable
{
    int DeleteState { get; set; }
}

Now I only have to add the IDeletable in the EF model:

public partial class Table : EntityObject, IDeletable { ... }

I did this with the templating mechanism.

Unfortunately, it doesn't work :( It compiles fine, but throws at runtime:

Unable to cast the type 'Table' to type 'IDeletable'. LINQ to Entities only supports casting Entity Data Model primitive types

if I call it like that:

Context.Table.Exists();

How can I solve this problem? Could you think of a fix or a different method to achieve similar results? Thx

4 Answers 4

0

The problem you have is that the Entity Framework can only work with an Expression Tree. Your function executes a query directly instead of building an Expression Tree.

A simpler solution would be to add a Model Defined Function.

A model defined function can be called directly on an instance of your context.

Sign up to request clarification or add additional context in comments.

Comments

0

Maybe:

public static IQueryable<T> Exists<T>(this IQueryable<T> qry)
{
    return qry.Where(x => (!typeof(IDeletable).IsAssignableFrom(x.GetType()) || typeof(IDeletable).IsAssignableFrom(x.GetType()) && ((IDeletable)x).DeleteState == 0));
}

Comments

0

Tsss, this is the answer: Linq Entity Framework generic filter method

I forgot about the class here:

... where T : class, IDeletable

3 Comments

If your solution works error you had at runtime does not seems good to me.
@vince: please elaborate. Exceptions aren't good in general :)
Does your solution work? did you try mine? I just said that if it works by addind class to generic constraint, the error "LINQ to Entities only supports casting Entity Data Model primitive types" does not have sense. It does not realy matter, it won't be the first exception without ^^
0

Have you tried converting your objects to IDeletable before you actually query? e.g.

public static IQueryable<T> Exists<T>(this IQueryable<T> qry)
{     
    return qry.Select<T, IDeletable>(x => x).Where(x => x.DeleteState == 0).Cast<T>();
}

I haven't tested this code, however, the error rings a bell and I remember I had to do something similar.

2 Comments

Hmm, I get the same runtime exception. Also a downside to this is that I get a different type from the select. It's not T anymore but IDeletable, right?
@duedl0r - Yeah but you can always just cast it back Where(x => x.DeleteState == 0).Cast<T>(). See my updated source, you will still be getting the issue if your still force T to be IDeletable in the method declaration.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.