动态表名是否可能运行查询SQL select语句?

时间:2020-04-10 01:17:43

标签: c# sql .net entity-framework-core ef-core-3.0

我使用以下代码在网站处于活动状态时动态创建表:

public void CreateTable(string tableName, string field1, double field2, ...)
{
  string Raw = string.Format("CREATE TABLE [{0}] ([ID] UNIQUEIDENTIFIER NOT NULL, [{1}] NVARCHAR (MAX) NOT NULL, [{2}] FLOAT NOT NULL, ..., , CONSTRAINT[PK_{0}] PRIMARY KEY CLUSTERED([ID] ASC);", tableName, field1, field2);
  _context.Database.ExecuteSqlRaw(Raw);
  _context.SaveChanges();
}

现在我要运行查询SQL,选择类似这样的内容::

private readonly ApplicationDbContext _context;
public HomeController(ApplicationDbContext context)
{
   _context = context;
}
public void List(string tableName)
{
   string Raw = string.Format("SELECT * FROM [{0}];", tableName);
   var table = _context.Database.ExecuteSqlRaw(Raw);
   //--- Do something with table here
}

注意: 我尝试使用这样的反射:

var table = _context.GetType().GetProperty(tableName).GetValue(_context) as IQueryable;

但无法正常工作并返回NULL。

我仍然是C#的新手,如果您能向我展示基于此代码的示例,我将不胜感激。

1 个答案:

答案 0 :(得分:0)

您可以使用Command来获取动态对象。

首先创建一个函数以获取数据行。

 public static IEnumerable<dynamic> CollectionFromSql(this DbContext dbContext, string Sql, Dictionary<string, object> Parameters)
{
    using (var cmd = dbContext.Database.GetDbConnection().CreateCommand())
    {
        cmd.CommandText = Sql;
        if (cmd.Connection.State != ConnectionState.Open)
            cmd.Connection.Open();

        foreach (KeyValuePair<string, object> param in Parameters)
        {
            DbParameter dbParameter = cmd.CreateParameter();
            dbParameter.ParameterName = param.Key;
            dbParameter.Value = param.Value;
            cmd.Parameters.Add(dbParameter);
        }

        //var retObject = new List<dynamic>();
        using (var dataReader = cmd.ExecuteReader())
        {

            while (dataReader.Read())
            {
                var dataRow = GetDataRow(dataReader);
                yield return dataRow ;

            }
        }


    }
}

然后将数据添加到动态对象。

private static dynamic GetDataRow(DbDataReader dataReader)
{
    var dataRow = new ExpandoObject() as IDictionary<string, object>;
    for (var fieldCount = 0; fieldCount < dataReader.FieldCount; fieldCount++)
        dataRow.Add(dataReader.GetName(fieldCount), dataReader[fieldCount]);
    return dataRow;
}

您可以这样使用:

List<dynamic> MyList = MyDbContext.CollectionFromSql("SELECT * FROM @tableName",
        new Dictionary<string, object> { { "@tableName", tableName } }).ToList();