如何实现不同项目下API列的动态分配并传递至React应用?
.NET后端实现方案
1. 基于#cols临时表生成安全动态查询
先从临时表提取列名,必须通过系统表验证列合法性来避免SQL注入,再拼接成可执行的动态SQL:
-- 假设业务表名为 [TargetTable],先过滤出合法列名 DECLARE @validColumns NVARCHAR(MAX); SELECT @validColumns = STRING_AGG(QUOTENAME(c.col_name), ', ') FROM #cols c JOIN INFORMATION_SCHEMA.COLUMNS ic ON c.col_name = ic.COLUMN_NAME AND ic.TABLE_NAME = 'TargetTable'; -- 生成并执行动态查询 DECLARE @dynamicSql NVARCHAR(MAX) = N'SELECT ' + @validColumns + N' FROM [TargetTable];'; EXEC sp_executesql @dynamicSql;
2. API接口返回结构化数据
在.NET控制器中,同时返回列配置元数据和业务数据,方便前端直接使用:
[HttpGet("dynamic-data")] public async Task<IActionResult> GetDynamicColumnsData() { using var connection = new SqlConnection(_configuration.GetConnectionString("Default")); await connection.OpenAsync(); // 执行存储过程,获取临时表列配置+业务数据 var multiResult = await connection.QueryMultipleAsync( "YourStoredProcedure", commandType: CommandType.StoredProcedure ); // 读取列配置(需和存储过程返回的#cols字段对应) var columnConfigs = multiResult.Read<ColumnMeta>().ToList(); // 读取业务数据(用动态类型适配不确定列) var data = multiResult.Read<dynamic>().ToList(); return Ok(new { Columns = columnConfigs, Data = data }); } // 列元数据实体类 public class ColumnMeta { public string ColName { get; set; } public string DisplayName { get; set; } // 存储过程可返回前端显示名 public string DataType { get; set; } }
React前端实现方案
1. 动态渲染表格组件
调用API后,根据返回的列配置生成表头和数据行(以原生HTML表格为例,框架组件逻辑一致):
import React, { useState, useEffect } from 'react'; import axios from 'axios'; const DynamicTable = () => { const [tableCols, setTableCols] = useState([]); const [tableData, setTableData] = useState([]); useEffect(() => { axios.get('/api/dynamic-data') .then(res => { // 转换列配置为表格渲染格式 const formattedCols = res.data.Columns.map(col => ({ key: col.ColName, title: col.DisplayName || col.ColName, dataKey: col.ColName })); setTableCols(formattedCols); setTableData(res.data.Data); }) .catch(err => console.error('加载数据失败:', err)); }, []); return ( <table border="1" cellPadding="8"> <thead> <tr> {tableCols.map(col => <th key={col.key}>{col.title}</th>)} </tr> </thead> <tbody> {tableData.map((row, idx) => ( <tr key={idx}> {tableCols.map(col => <td key={col.key}>{row[col.dataKey]}</td>)} </tr> ))} </tbody> </table> ); }; export default DynamicTable;
2. 特殊数据类型处理(可选)
如果存储过程返回数据类型,前端可针对性格式化:
const formattedCols = res.data.Columns.map(col => ({ key: col.ColName, title: col.DisplayName || col.ColName, dataKey: col.ColName, format: (value) => { if (col.DataType === 'datetime') return new Date(value).toLocaleDateString(); if (col.DataType === 'decimal') return Number(value).toFixed(2); return value; } })); // 渲染时调用format <td key={col.key}>{col.format(row[col.dataKey])}</td>
内容的提问来源于stack exchange,提问作者user23577668
相关产品推荐
相关产品推荐

