ASP.NET Core多表查询复用代码及直接执行SQL方案咨询
动态查询不同数据表的解决方案(ASP.NET Core)
一、EF Core中用变量指定表名(含风险提示)
如果想用变量指定表名来复用查询逻辑,直接用EF Core的FromSqlRaw方法即可,对应你给出的示例,修改方式如下:
string tblname = "users"; // 先做安全校验:限定表名在允许列表内,避免SQL注入 var allowedTables = new List<string> { "users", "blogs", "orders" }; if (!allowedTables.Contains(tblname.ToLower())) { throw new ArgumentException("非法表名"); } // 执行查询,注意<T>要对应表的实体类 var retdata = context.Set<User>().FromSqlRaw($"SELECT * FROM {tblname}").ToList();
重要提醒:直接拼接表名存在SQL注入风险,必须对传入的表名做严格校验,比如只允许预设的合法表名,绝对不能直接使用用户输入的未校验值。
二、直接执行SQL命令(绕过EF Core实体映射)
如果不需要通过EF的DbSet,想直接执行原生SQL命令,有两种常见方式:
1. 返回强类型数据
如果有对应的数据实体类,可以用SqlQuery方法(需引用Microsoft.EntityFrameworkCore.Relational包):
string tblname = "users"; var allowedTables = new List<string> { "users", "blogs" }; if (!allowedTables.Contains(tblname.ToLower())) { throw new ArgumentException("非法表名"); } var result = context.Database.SqlQuery<User>($"SELECT * FROM {tblname}").ToList();
2. 返回非强类型/自定义数据
如果不需要实体映射,直接用DbDataReader读取原始数据:
string tblname = "users"; var allowedTables = new List<string> { "users", "blogs" }; if (!allowedTables.Contains(tblname.ToLower())) { throw new ArgumentException("非法表名"); } using (var command = context.Database.GetDbConnection().CreateCommand()) { command.CommandText = $"SELECT * FROM {tblname}"; context.Database.OpenConnection(); using (var reader = command.ExecuteReader()) { while (reader.Read()) { // 按列读取数据,示例: int id = reader.GetInt32(reader.GetOrdinal("Id")); string name = reader.GetString(reader.GetOrdinal("Name")); // 自行处理读取到的数据 } } }
三、封装通用方法避免重复代码
把校验和查询逻辑封装成通用方法,以后直接调用即可:
public List<T> QueryTable<T>(string tableName) where T : class { var allowedTables = new List<string> { "users", "blogs", "orders" }; if (!allowedTables.Contains(tableName.ToLower())) { throw new ArgumentException("非法表名"); } return context.Set<T>().FromSqlRaw($"SELECT * FROM {tableName}").ToList(); } // 使用示例 var users = QueryTable<User>("users"); var blogs = QueryTable<Blog>("blogs");
内容的提问来源于stack exchange,提问作者Alireza Alirezai
相关产品推荐
相关产品推荐

