0

Предположим, у меня есть класс Parent с двумя подклассами, AChild и BChild. Я сопоставил их с одной таблицей, используя Entity Framework 5.0.0 на .NET 4.5, используя TPH.Entity Framework TPH - Дополнительное предложение WHERE только для одного подтипа

public abstract class Parent { 
    public string Type { get; set; } // Column with this name in DB is discriminator. 
    public string Status { get; set; } 
} 

public class AChild : Parent { 
    // Other stuff. 
} 

public class BChild : Parent { 
    // Other stuff. 
} 

Код для настройки отображения:

class ParentConfiguration : EntityTypeConfiguration<Parent> { 
    Map((EntityMappingConfiguration<AChild> mapping) => mapping 
     .Requires("Type") 
     .HasValue("A")); 
    Map((EntityMappingConfiguration<BChild> mapping) => mapping 
     .Requires("Type") 
     .HasValue("B")); 
} 

У меня есть необходимость выполнения запроса, который возвращает как AChild и объекты BChild. Тем не менее, он должен фильтровать ТОЛЬКО строки AChild вторым столбцом, который в этом примере я вызову Status.

В идеале я хотел бы сделать следующее:

public IList<Parent> RunQuery() { 
    IQueryable<Parent> query = 
     this.context.Set<Parent>() 
     .Where((Parent parent) => !parent.Type.Equals("A") || parent.Status.Equals("Foo")) 
     .OrderBy((Parent parent) => parent.Number); 
    return query.ToList(); 
} 

Это не работает. Он настаивал на поиске столбца «Type1» вместо того, чтобы просто назначать как дискриминатор, так и свойство «Тип» в один и тот же столбец «Тип».

Я знаю метод расширения «OfType», который можно использовать для полного фильтрации до одного типа, но в этом случае это слишком широкая кисть.

Я мог бы запустить несколько запросов и объединить результаты, но фактическая система, которую я создаю, выполняет подкачку, поэтому, если мне нужно отбросить 10 строк, она становится беспорядочной (и неэффективной) для запроса, поскольку я буду либо в конечном итоге вытягивать слишком много строк, либо не оттягивать достаточно, а выполнять лишние запросы.

Есть ли у кого-нибудь другие мысли?

ответ

1

Есть несколько проблем. Прежде всего, вы не можете распознать дискриминатор как свойство. Именно по этой причине он ищет столбец Type1 - ваше свойство Type приводит ко второму столбцу, потому что первое уже сопоставлено с типами .NET ваших классов. Единственный способ фильтровать производные типы - OfType.

Запрос, который вы хотите построить, будет, вероятно, довольно сложным, потому что вам нужно запросить все Bs и объединить их с результатом запроса для фильтров As. Скорее всего, это не позволит вам конкатенировать экземпляры Bs с As, поэтому вам придется преобразовать их обратно в родительский тип.

+0

Да, это, по-видимому, является ограничением EF. В идеальном мире мы могли бы также сопоставить дискриминатор с свойством - это позволило бы гораздо большей гибкости при запросе. Может быть, я добавлю это к uservoice. –

Смежные вопросы