2011-12-16 2 views
2

В моей БД у меня есть таблицы, у которых есть атрибут int DeleteState. Я хочу, чтобы общий метод запрашивал эти таблицы. Другими словами, метод, который делает это: Context.Table.Where(x => x.DeleteState == 0).Общий метод запросов в Entity Framework

Я думал, что я мог бы сделать это:

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

Где IDeletable это:

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

Теперь я только добавить IDeletable в модели EF:

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

Я сделал это с помощью механизма шаблонов.

К сожалению, это не работает :(Это компилируется нормально, но броски во время выполнения:

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

, если я называю это так:

Context.Table.Exists(); 

Как я могу решить эту проблему проблема? Не могли бы вы придумать исправление или другой метод для достижения аналогичных результатов? Thx

ответ

0

Tsss, это ответ: Linq Entity Framework generic filter method

Я забыл о class здесь:

... где T: класс, IDeletable

+0

Если ваше решение работает с ошибкой, которую вы имели во время выполнения, мне не кажется хорошо. – Vince

+0

@ vince: пожалуйста уточните.Исключения вообще не хороши :) – duedl0r

+0

Работает ли ваше решение? ты пытался мой? Я просто сказал, что если он работает с помощью класса addind с общим ограничением, ошибка «LINQ to Entities поддерживает только приведение примитивных типов данных Entity Data Model» не имеет смысла. Это не имеет большого значения, это не будет первое исключение без ^^ – Vince

0

Проблема заключается в том, что Entity Framework может только wo rk с деревом выражений. Ваша функция выполняет запрос напрямую, а не создает дерево выражений.

Более простым решением было бы добавить Model Defined Function.

Определенная модель может быть вызвана непосредственно на экземпляр вашего контекста.

+0

Thx, good hi нт. – duedl0r

0

Вы пытались преобразовать свои объекты в IDeletable, прежде чем вы действительно запрашиваете? например

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

Я не проверял этот код, однако, ошибка звонит в колокольчик, и я помню, что я должен был сделать что-то подобное.

+0

Хмм, я получаю такое же исключение во время выполнения. Также недостатком является то, что я получаю другой тип от выбора. Это уже не Т, а IDeletable, верно? – duedl0r

+0

@ duedl0r - Да, но вы всегда можете просто отбросить его обратно. Где (x => x.DeleteState == 0) .Cast () '. См. Мой обновленный источник, вы все равно получите проблему, если ваша сила T будет «IDeletable» в объявлении метода. – James

0

Может быть:

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)); 
} 
Смежные вопросы