基于表模式

时间:2017-08-27 01:19:56

标签: c# sql-server entity-framework reflection

我想根据用户提交的查询结果动态生成一个类。例如,如果用户输入Select name, age from tbl,则结果是namestringage,这是一个int。结果类应为:

public class Test
{
   public string Name { get; set; }
   public int Age { get; set; }
}

是否有一种有效的方法可以通过EntityFramework或C#中的功能执行此操作,或者我必须使用反射来创建新类型并实例化它。

PS:我的目的是在数据库上运行此查询,并在网格中向用户显示结果并运行一些过滤器/排序/等。在它上面。

1 个答案:

答案 0 :(得分:2)

您可以使用TypeBuilder创建新类型,并使用EF SqlQuery()提及here对数据库执行查询。

更简洁的方法是使用dynamic个对象来绑定网格。根据 ChristineBoersen here的建议,扩展EF以返回dynamic个对象的集合。代码是在EF进入RTM之前编写的。这是一个有效的版本:

public static class EFExtensions
{
    public static IEnumerable<dynamic> CollectionFromSql(this DbContext dbContext, string Sql, Dictionary<string, object> Parameters)
    {
        using (var cmd = dbContext.Database.Connection.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;
    }
}

您可以按如下方式调用上述方法:

var results = context.CollectionFromSql("Select Name, Age from tbl", new Dictionary<string, object>()).ToList();
// Bind results to grid