#c# #.net #entity-framework
#c# #.net #entity-framework
Вопрос:
I класс поставщика:
public class Supplier {
....
....
....
}
У меня также есть класс Subjector, а Subjector является поставщиком:
public class Subcontractor:Supplier {
....
....
....
}
В моей базе данных у меня есть таблица поставщиков с данными и другая таблица с полем id, которое действует как внешний ключ к таблице поставщиков, и у меня там также есть данные вложенного компилятора.
В файле edmx entity Framework я объявил отношение наследования:
Теперь я хочу получить всех поставщиков, которые не являются субподрядчиками, поэтому я делаю:
context.Suppliers.OfType<Supplier>();
Но это возвращает также субподрядчиков..
Как я могу получить только поставщиков, которые не являются субподрядчиками?
Ответ №1:
Попробуйте:
context.Suppliers.Where(s => !(s is Subcontractor));
Редактировать
Если у вас есть более одного класса, который является производным от Supplier
, единственный вариант с LINQ to Entities выглядит примерно так:
context.Suppliers.Where(s => !(s is Subcontractor)
amp;amp; !(s is DerivedClass2)
amp;amp; !(s is DerivedClass3)); // etc.
Entity SQL поддерживает ключевое слово ONLY, которое позволяет запрашивать определенный тип. Но соответствующий аналог недоступен в качестве оператора LINQ.
Здесь представлена реализация OfTypeOnly<TEntity>
оператора, но она интенсивно использует информацию метаданных и построение выражений вручную и может быть излишней в простых сценариях.
Комментарии:
1. Что, если субподрядчик — это всего лишь один из 5 типов, производных от поставщика?.. Тогда мне придется добавить 5 wheres.
2. @Naor: К сожалению, кажется, что нет простого способа, смотрите Мою правку выше. По крайней мере, я не смог найти простого решения.
Ответ №2:
В настоящее время я использую следующее расширение LINQ, предполагая, что подклассы расположены в одной сборке.
public static class MyLinqExtensions
{
public static IQueryable<T> OfTypeOnly<T>(this IQueryable<T> query)
{
Type type = typeof (T);
IEnumerable<Type> derivedTypes = Assembly
.GetAssembly(type)
.GetTypes()
.Where(t => t.IsSubclassOf(type));
return query.ExceptTypes(derivedTypes.ToArray());
}
public static IQueryable<T> ExceptTypes<T>(this IQueryable<T> query, params Type[] excludedTypes)
{
if (excludedTypes == null)
return query;
return excludedTypes.Aggregate(query,
(current, excludedType) => current.Where(entity => entity.GetType() != excludedType));
}
}
Использование:
// Get only entities of type Supplier, excluding subclasses.
var suppliers = context.Suppliers.OfTypeOnly<Supplier>();
Ответ №3:
context.Suppliers.Where(s => s.GetType() == typeof(Supplier));
Комментарии:
1. Это не работает в LINQ для сущностей;
GetType
не может быть переведено в выражение хранилища.