Как сделать запрос к базе данных, когда ее таблицы создаются во время выполнения - PullRequest
0 голосов
/ 03 марта 2019

Я успешно нашел способ создания базы данных и таблиц во время выполнения, проблема в том, что я не знаю, как запросить эту базу данных, учитывая, что таблицы создаются путем переопределения метода OnModelCreating.

Вот мой код для DbContext:

public class DataDbContext : DbContext 
{
    public string ConnectionString { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(ConnectionString);

    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        MyClassBuilder MCB = new MyClassBuilder("Student");
        var myclass = MCB.CreateObject(new string[3] { "ID", "Name", "Address" },
            new Type[3] { typeof(int), typeof(string), typeof(string) });

        Type type = myclass.GetType();

        var entityMethod = typeof(ModelBuilder).GetMethod("Entity", new Type[] { });
        if (type.IsClass)
        {
            entityMethod.MakeGenericMethod(type)
                .Invoke(modelBuilder, new object[] { });
        }
        base.OnModelCreating(modelBuilder);
    }
}

Первые три строки в OnModelCreating создают класс во время выполнения с определенными свойствами [id , name, address].

Послепри выполнении

{
  dataDbContext.Database.EnsureCreated();
}

база данных создается с таблицей с именем Student, содержащей три столбца [id , name, address], как и ожидалось.Как я уже сказал, проблема в том, что я не знаю, как запросить эту базу данных

Есть идеи?

Спасибо

Ответы [ 2 ]

0 голосов
/ 03 марта 2019

Извините, phyzia1996, но я не могу сделать это с помощью класса DbContext.DbSet хочет получить конкретный класс и обойти это не только за пределами меня, но и очень сложно.Глубокое погружение в классы Reflection и DbContext.Если бы мне нужно было работать с динамическими классами в базе данных, я бы использовал что-то вроде этого.Большая часть кода ниже может быть расширена с помощью Reflection, строка запроса может быть построена во время выполнения путем сканирования свойств динамического класса и т. Д.

class ReadStudents
{
    public string ConnectionString = @"Server=(localdb)\mssqllocaldb;Database=Blogging;Trusted_Connection=True;";
    public List<dynamic> GetAllStudents()
    {
        dynamic student_rec = new ExpandoObject();
        List<dynamic> rtn_list = new List<dynamic>();
        using (SqlConnection sql_con = new SqlConnection(ConnectionString))
        {
            using (SqlCommand sql_cmd = new SqlCommand())
            {
                sql_con.Open();
                sql_cmd.Connection = sql_con;
                sql_cmd.CommandText = "Select ID, Name, Address from Student";
                SqlDataReader sql_rdr = sql_cmd.ExecuteReader();
                while ( sql_rdr.Read() )
                {
                    student_rec.Id = sql_rdr[0].ToString();
                    student_rec.Name = sql_rdr[1].ToString();
                    student_rec.Address = sql_rdr[2].ToString();
                    rtn_list.Add(student_rec);
                }
            }
        }
        return rtn_list;
    }
}

В любом случае, извините, я не смог помочь, но сделал этонаслаждайтесь R & D.

0 голосов
/ 03 марта 2019

Обновление: Это не работает, «объект» определен как одноэлементный, он не реализует какой-либо IEnumerable, поэтому вы можете одновременно получить доступ только к одному объекту DbContext ENTITY.Он может вставлять одну строку за раз, но не намного больше.Я буду продолжать исследовать это, пока не найду решение, или кто-то другой не сможет предоставить правильное решение.

Для тех, кто интересуется вещью MyClassBuilder , вы можете найти это здесь, в StackOverflow Как использовать динамически создаваемый класс в List .Престижность тому, кто написал, что это очень крутая штука.

Это все еще в стадии разработки, но это должно помочь, и я все еще работаю над этим.На данный момент 1. Определите динамический класс как «объект» в классе DataDbContext.2. Создайте динамический класс в конструкторе DataDbContext.3. Ссылка на динамический класс с помощью «объекта» в переопределении OnModelCreating. Новый класс DataDbContext будет выглядеть следующим образом

public class DataDbContext : DbContext
{
    public string ConnectionString = @"Server=(localdb)\mssqllocaldb;Database=Blogging;Trusted_Connection=True;";
    public object myclass;  // define the class outside of the OnModelCreating override
    public DataDbContext()
    {   // create the class in the consrtuctor 
        MyClassBuilder MCB = new MyClassBuilder("Student");
        var type_array = new Type[3] { typeof(int), typeof(string), typeof(string) };
        myclass = MCB.CreateObject(new string[3] { "ID", "Name", "Address" }, type_array);
        Type type = myclass.GetType();
    }
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    { optionsBuilder.UseSqlServer(ConnectionString); }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        Type type = myclass.GetType();
        var entityMethod = typeof(ModelBuilder).GetMethod("Entity", new Type[] { });
        if (type.IsClass)
        { entityMethod.MakeGenericMethod(type).Invoke(modelBuilder, new object[] { }); }
        base.OnModelCreating(modelBuilder);
    }
}

Я все еще работаю с «получает», я обновлю этот ответ, когда у меня будетэто, но «наборы» будут использовать отражение против динамического класса, чтобы получить свойства и установить их.Затем DbContext сохранит изменения, аналогичные тем, которые вы использовали при использовании команды DbSet.Метод AddStudent будет выглядеть следующим образом. ОБНОВЛЕНИЕ Я пропустил поле идентификатора, поскольку оно было установлено как вставка идентификатора, вы все равно можете получить свойство, но не устанавливать его, или Sql Server будет жаловаться на ненулевое значение для столбца вставки идентификатора.Мой метод «get» справится с этим, как только я пойму, как это сделать.

    public static void AddStudent(string student_name, string student_address)
    {
        using (DataDbContext dataDbContext = new DataDbContext())
        {
            dataDbContext.Database.EnsureCreated();

            PropertyInfo[] fields = dataDbContext.myclass.GetType().GetProperties();
            PropertyInfo prop_name = fields[1];
            PropertyInfo prop_addr = fields[2];
            prop_name.SetValue(dataDbContext.myclass, student_name);
            prop_addr.SetValue(dataDbContext.myclass, student_address);

            dataDbContext.Add(dataDbContext.myclass);
            dataDbContext.SaveChanges();
        }
    }

Как я уже упоминал выше, я все еще работаю над этим, но я хотел сказать спасибо, это было очень крутовопрос, довольно сложный :) 1020 *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...