Получить запись из БД, используя отражение и общий тип

Я хочу получить экземпляр из БД. Я создал модель БД, используя EF. Я могу сделать это статическим способом:

var tempRecord= db.Table1.First(a => a.column1 ==  columnValue);

Но как это сделать, если класс текущей таблицы меняется и иногда это Table1, а иногда Table2? Я пробовал что-то вроде этого, но, очевидно, это не работает:

Type entityType = Type.GetType(currentTable);
var tempRecord2 = db.entityType.First(a => a.column1 == columnValue);

Обновлено: currentTable - это строка

Существует 5 таблиц, и для каждой таблицы нужны разные столбцы для проверки. Итак, у меня был бы список столбцов, которые нужно проверить для каждой таблицы.

Вы можете использовать db.currentTable.First(a => a.column1 == columnValue). Вы пробовали это?

sri harsha 05.03.2019 13:12

currentTable — это строка

Pomme De Terre 05.03.2019 13:22

Это только две таблицы или потенциально больше? Если только две таблицы, просто запросите их обе и проверьте, являются ли сущности нулевыми :-)

Bo Mortensen 05.03.2019 13:42

Существует 5 таблиц, и для каждой таблицы нужны разные столбцы для проверки. Итак, у меня был бы список столбцов, которые нужно проверить для каждой таблицы.

Pomme De Terre 05.03.2019 13:44

Хорошо, не могли бы вы вставить скриншот своих таблиц и их взаимосвязей? Возможно, есть место для структурных улучшений :-)

Bo Mortensen 05.03.2019 13:47

столбцы в разных таблицах имеют одинаковое имя? и они последовательны?

iCode4U 05.03.2019 13:51

Что я не могу сделать, к сожалению. И как это поможет? Предположим, у меня есть одна таблица, и мы не знаем ее тип. Это все, что мне нужно, но я искал и искал, и не могу найти решения, кроме переключения регистра и написания чего-то статического.

Pomme De Terre 05.03.2019 13:53

Вы пытались настроить общий метод с помощью where T : YourEntityTypeClass? проблема в том, что каждый объект должен иметь столбец column1..

fhcimolin 05.03.2019 13:54

Некоторые одинаковы некоторые нет. Отношения описаны в таблице сопоставления, из которой я могу получить необходимые имена столбцов.

Pomme De Terre 05.03.2019 13:54

@ Passer7by это может помочь, потому что, когда вам нужно запросить несколько таблиц для одного и того же значения, это может означать, что дизайн БД может быть оптимизирован. Не пытаюсь быть грубым здесь :-) Либо сделайте несколько запросов и проверьте нулевые значения, либо, как предложил fhcimolin, сделайте свой метод универсальным.

Bo Mortensen 05.03.2019 14:11

@BoMortensen Я знаю, что ты не груб. Извините, если я пришел в качестве защиты. Есть ли другой подход? Потому что для каждой таблицы у меня будут разные столбцы для проверки, чтобы получить эту конкретную запись.

Pomme De Terre 05.03.2019 14:16

@ Passer7by, все хорошо :-) Хммм ... вам придется немного поколдовать над отражением, чтобы проверить столбцы различий для каждой из таблиц. Сначала проверьте, имеет ли универсальный объект свойство значения, которое нужно проверить, а затем проверьте само значение. Возможно, было бы лучше просто запросить в базе данных все необходимые таблицы, а затем выполнить проверки с результатом в памяти.

Bo Mortensen 05.03.2019 14:51
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
12
488
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Я предлагаю взглянуть на ответ это, если он вас вдохновит.

В нем код опирается на универсальные функции, передавая LINQ Func<> для делегирования First() (или, в его случае, SingleOrDefault()), чтобы он мог выполнять один и тот же метод для любого ObjectSet (или таблицы), который отправляется методу, точно так же, как снизу:

 public T Single<T>(System.Linq.Expressions.Expression<Func<T, bool>> expression) where T:class {
        return GetObjectSet<T>().SingleOrDefault(expression);
    }

Все идет нормально. Но в этом случае все ваши столбцы должны были бы называться column1. Но предлагается получить первичный ключ, что также объясняется далее в связанном ответе.

Это может помочь:

    Type entityType = Type.GetType("MyNameSpace.Models.City");
    var result = ((IQueryable<object>)db.Set(entityType)).FirstOrDefault();

кроме проверки столбцов.
Одним из возможных решений для добавления проверки столбцов является использование родительского класса, который содержит все поля, участвующие в фильтрации всех таблиц, и изменение второй строки следующим образом:

var result = ((IQueryable<ParentClass>)db.Set(entity)).First(a => a.column1 == columnValue);

Если дело в том, что у вас Только есть пять таблиц с одним и тем же столбцом, и вам нужно запросить базу данных для каждой из этих таблиц для этого столбца, а затем после выполнить проверки по результату для столбцов разные, то я думаю, что я бы пошел на Решение KISS, а не использование отражения.

Учитывая этот пример таблиц:

Table1
    ColumnA, Table1ColumnB, Table1ColumnC

Table2
    ColumnA, Table2ColumnB, Table2ColumnC

Table3
    ColumnA, Table3ColumnB, Table3ColumnC

И если больше не нужно добавлять таблицы, я бы запросил их следующим образом:

using(var ctx = new MyDbContext())
{
    Table1 tbl1 = ctx.Table1s.FirstOrDefault(x => x.ColumnA == "myvalue");
    Table2 tbl2 = ctx.Table2s.FirstOrDefault(x => x.ColumnA == "myvalue");
    Table3 tbl3 = ctx.Table3s.FirstOrDefault(x => x.ColumnA == "myvalue");

    // Perform null checks and other checks against different columns here
} 

В общем, не заморачивайтесь :-)

Предполагая, что «column1» является общим свойством, вы можете использовать этот метод:

        Type type = Type.GetType(currentTable);
        IEnumerable a = db.Database.SqlQuery(type, "SELECT * FROM " + name + " WHERE column1 = " + "x");

Затем, в зависимости от базы данных, измените запрос и получите первую строку или выполните преобразование во время выполнения и используйте First().

Другие вопросы по теме