#c# #postgresql #types #dbcontext #dbset
#c# #postgresql #типы #dbcontext #dbset ( набор данных ) #dbset
Вопрос:
У меня есть класс DbContext, в котором, например, записаны два параметра DbSet для работы с двумя таблицами.
public EntityCoreContext()
{
}
public EntityCoreContext(DbContextOptions<EntityCoreContext> options)
: base(options)
{
}
public virtual DbSet<Languages> Languages { get; set; }
public virtual DbSet<Users> Users { get; set; }
Я знаю, что для получения данных из контекста я должен написать: dbContext.Users.ToList ();
или dbContext.Languages.ToList();
Мне нужно сделать так, чтобы я мог получать данные, не вызывая напрямую таблицу по ее имени. Из серии: dbContext.Get<Users>().ToList();
или dbContext.Get<Languages>().ToList();
Ну, или другим способом. Так что метод, с помощью которого будет вызываться таблица, является универсальным. И поддерживает все любые таблицы, которые будут переданы ему.Это должно быть сделано для следующих методов: Insert, Update, Get, Delete.
Комментарии:
1. Вам не нужно ничего из этого, так как это именно то, для чего предназначены DbContext и DbSet. Это не таблицы, это объекты на стороне приложения. DbContext — это не соединение или модель базы данных, это единица измерения. И нет необходимости в методах, подобных объекту данных, поскольку ORM уже обрабатывает операции для нескольких объектов одновременно
2. Методы, которые вы хотите создать, не просто повредят производительности, они логически неверны. DbContext — это рабочая единица, поэтому он кэширует изменения до тех пор, пока его не попросят сохранить все из них. То
Insert()
, что вы хотите создать, также может легко выполнить 500 удалений. Отсутствие необходимости в репозитории или единице работы с Entity Framework Core от Гуннара Пейпмана показывает, насколько ошибочна эта попытка3. Вы пытаетесь наложить низкоуровневый интерфейс доступа к данным-объекту поверх высокоуровневого ORM. Это плохая идея, признанная таковой еще в 2009 году, когда NHibernate сделал ORM популярными в .NET и заменил эти интерфейсы «общего хранилища». Орен Эйни, сопровождающий NHibernate в то время, объяснил это в репозитории нового синглтона
4. Наконец ,
dbContext.Get<User>()
это так же жестко запрограммировано, какdbContext.Users
. Вам все равно нужно знать тип объекта при компиляции, ноGet<User>
он не предупредит вас, если используется неправильный тип.5. Какую актуальную проблему вы хотите решить?
So that the method that the table will be called by is universal.
DbContext уже является универсальным. Вы столкнулись с конкретной проблемой и подумали, что вам нужно больше гибкости? Возможно, пытаетесь создать настраиваемый пользователем редактор открытых запросов? Или запрос отчета, который работает с любым контекстом? Это может быть сложно и часто не подходит для использования с ORM. Хотя простой CRUD, отключенные операции, транзакционные изменения просты и уже реализованы
Ответ №1:
В EntityFramework существует .Set<T>()
метод, который возвращает DbSet
в соответствии с переданным типом.
Таким образом, вы могли бы использовать:
dbContext.Set<Users>().ToList();
Я знаю, что это странное именование, но Set
метод здесь возвращает DbSet
, он ничего не устанавливает.
Комментарии:
1. Или не использовать их вообще, поскольку настроенный DbContext уже делает все это. Нет необходимости в «динамических» именах таблиц — для начала нет имен таблиц, они являются объектами на стороне приложения. DbContext — это не соединение или модель базы данных, это единица работы, нет необходимости в репозиториях, вот что такое DbSet. И также нет необходимости в методах модификации одного объекта
2. И в именовании нет ничего странного. Метод возвращает набор. Явных методов модификации нет, потому что ни один из них не требуется — SaveChanges сохранит все изменения
Ответ №2:
Не уверен, в чем выгода, но что-то вроде этого:
public IQueryable<T> GetEntity() where T : class
{
using (EntityCoreContext ctx = new EntityCoreContext())
{
return ctx.Set<T>();
}
}
Комментарии:
1. Жарко это использовать?
2. Создайте (вспомогательный) класс, содержащий метод GetEntity, и используйте его там, где вы хотите. Почему вы хотите сделать это таким образом, если я могу спросить?