Я использую Entity Framework с большой базой данных (состоящей из более чем 200 таблиц).
Попытка создать общий метод, который возвращает DbSet<T>
конкретной таблицы T
(т.е. класс, который может быть TableA
).
Класс сущности, который был (автоматически) создан с использованием модели данных сущности, выглядит так:
public partial class sqlEntities : DbContext
{
public virtual DbSet<TableA> TableA { get; set; }
public virtual DbSet<TableB> TableB { get; set; }
public virtual DbSet<TableC> TableC { get; set; }
... // other methods
}
Мой основной класс похож на этот
public class TableModifier
{
// Should return first 10 elements from a table of that type T
public IQueryable<T> GetFromDatabase<T>() where T : EntityObject
{
try
{
using (sqlEntities ctx = new sqlEntities())
{
// Get the DbSet of the type T from the entities model (i.e. DB)
DbSet<T> dbSet = ctx.Set<T>();
return dbSet.Take(10);
}
}
catch (Exception ex)
{
// Invalid type was provided (i.e. table does not exist in database)
throw new ArgumentException("Invalid Entity", ex);
}
}
... // other methods
}
Мне нужно установить ограничение where T : EntityObject
на T
в пределах EntityObject
. Если бы такого ограничения не было, тогда DbSet<T> dbSet
будет жаловаться (т.е. T должен быть ссылочным типом), что он может получить больше, чем он ожидает в терминах типов (на основе).
Проблема возникает, когда я пытаюсь вызвать метод с определенным типом.
[TestMethod]
public void Test_GetTest()
{
TableModifier t_modifier = new TableModifier();
// The get method now only accepts types of type EntityObject
IQueryable<TableA> i_q = t_modifier.GetFromDatabase<TableA>();
}
Это дает ошибку:
There is no implicit reference conversion from 'TableMod.TableA' to
'System.Data.Entity.Core.Objects.DataClasses.EntityObject'.
Как я могу (cast?) тип TableA
как EntityObject
, если я знаю, что он существует для этой модели сущности?
Хотя это неправильный синтаксис (и логика), это то, что мне нужно:
t_modifier.GetFromDatabase<(EntityObject)TableA>();
Как я могу определить TableA
(вместе со всеми другими 200 таблицами), чтобы быть частью EntityObject
?
Потенциальное решение
Оказывается, мое ограничение было слишком специфичным, все, что мне нужно было изменить, было от where T : IEntity
до
where T : class
Итак, T
- это то, что первоначально ожидалось DbSet<T>
, тип класса
Сохраняет проблему добавления реализаций к 200 + классам таблиц, TableA
, TableB
,...
Тогда, конечно, существуют и другие проблемы, такие как изменение типа возврата из IQueryable<T>
в List<T>
, поскольку в противном случае IQueryable
был бы возвращен за пределы области DbContext
(т.е. sqlEntities
), что делает его бесполезным.