在运行时创建表时如何查询数据库

时间:2019-03-03 01:16:03

标签: c# asp.net-core entity-framework-core

我已经成功地找到了一种在运行时创建数据库和表的方法,问题是鉴于表是通过覆盖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 :(得分:0)

更新: 这不起作用,“对象”被定义为单例,它没有实现任何IEnumerable类型,因此您一次只能访问一个DbContext ENTITY。它一次只能插入一行,但不能插入太多。在找到解决方案或其他人可以提供合适的解决方案之前,我将继续进行研究。

对于那些对 MyClassBuilder 感到疑惑的人,您可以在StackOverflow How use Dynamic created class in List<T>上找到它。不论写什么的人都感到很荣幸。

这仍在进行中,但应该会有所帮助,我仍在努力。目前 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);
    }
}

我仍在使用“ gets”,如果有,我将更新此答案,但是“ sets”将对动态类使用反射以获取属性并进行设置。然后,DbContext将保存与使用DbSet命令类似的更改。 “ AddStudent”方法如下所示。 更新我跳过了ID字段,因为它被设置为“身份插入”,您仍然可以获取该属性,但不对其进行设置,否则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();
        }
    }

如上所述,我仍在努力充实,但我想说谢谢,这是一个非常酷的问题,很有挑战性:)

答案 1 :(得分:0)

对不起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;
    }
}

无论如何,对不起,我无济于事,但我确实很喜欢研发。