由于在表格中的项目列表上进行了旋转,因此我有一组不断变化的列。基本上,您在上图中看到的每列都是数据库表中的一行。我想在前端显示一组线作为一行。如何从控制器或api返回此动态类型?
我一直试图使用这样的代码。
List<dynamic> items = repository.GetAll();
foreach(var item in items){
var properties = item.GetType().GetProperties(BindingFlags.Public);
foreach (var property in properties) {
var PropertyName = property.Name;
var PropertyValue = item.GetType().GetProperty(property.Name).GetValue(item, null);
model.Add(PropertyName, PropertyValue);
}
}
但GetProperties()不会从动态&#34;项目&#34;中返回任何内容。我也尝试过使用item.GetType()。GetFields()无济于事 当我不知道该列的名称时,如何从c#中获取动态数据类型的列名和值?或者只是从api返回动态对象?感谢。
这是存储库代码。
public IEnumerable<dynamic> GetAll()
{
var items = context.Database.SqlQuery<dynamic>(
"DECLARE @cols NVARCHAR(MAX), @sql NVARCHAR(MAX)" +
"SET @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(FormDetails.Name)" +
" from Value" +
" left join ValueDetails" +
" on Value.Id = ValueDetails.ValueId" +
" left" +
" join FormDetails" +
" on ValueDetails.FormDetailsId = FormDetails.Id" +
" ORDER BY 1" +
" FOR XML PATH(''), TYPE" +
" ).value('.', 'NVARCHAR(MAX)'), 1, 1, '')" +
" SET @sql = 'SELECT Id, FormId, CreatedDateTime, ' + @cols + '" +
" FROM" +
" (" +
" select Value.Id, Value.FormId, FormDetails.Name, ValueDetails.Value, Value.CreatedDateTime" +
" from Value" +
" left join ValueDetails" +
" on Value.Id = ValueDetails.ValueId" +
" left" +
" join FormDetails" +
" on ValueDetails.FormDetailsId = FormDetails.Id" +
" ) s" +
" PIVOT" +
"(" +
"MAX(Value) FOR Name IN(' + @cols + ')" +
") p order by CreatedDateTime desc '" +
" EXECUTE(@sql)").ToList();
return items;
}
这里有更多信息。基本上我的存储库返回本页顶部第一个图像的数据。但是当我将数据返回到前端时,这就是它的样子。对象在那里,但没有属性...
答案 0 :(得分:1)
您的代码的问题不在于获取一个空的属性列表,因为它们确实不存在。如果属性SqlQuery<T>
上没有属性,T
将不会填充该属性;您传递dynamic
,转换为System.Object
。
解决此问题的一个技巧是动态检索列名,并从中构建ExpandoObject
。该技术被描述为here。
static IList<dynamic> Read(DbDataReader reader) {
var res= new List<Dictionary<string,object>>();
foreach (var item in reader) {
IDictionary<string,object> expando = new ExpandoObject();
foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(item)) {
var obj = propertyDescriptor.GetValue(item);
expando.Add(propertyDescriptor.Name, obj);
}
res.Add(expando);
}
return res;
}
使用此方法,请致电
using (var cmd = ctx.Database.Connection.CreateCommand()) {
ctx.Database.Connection.Open();
cmd.CommandText = ...; // Your big SQL goes here
using (var reader = cmd.ExecuteReader()) {
return Read(reader).ToList();
}
}
一旦您的存储库开始返回ExpandoObject
,您的代码可以替换为代码查询IDictionary<string,object>
,这是ExpandoObject
实现的接口:
IDictionary<string,object> properties = item as IDictionary<string,object>;
if (properties != null) {
foreach (var p in properties) {
model.Add(p.Key, p.Value);
}
}