Web API 2结合EF通过动态参数查询多实体遇数据读取器兼容错误
解决EF与Web API 2中实体映射不匹配及动态查询问题
你遇到的EntityCommandExecutionException错误根源非常清晰:你的EF实体类ADRESSE中的ADRESSE1属性,和数据库表ADRESSE里的ADRESSE列名称不匹配。EF默认按照属性名与数据库列名完全一致的规则进行映射,当数据读取器返回ADRESSE列时,找不到对应的ADRESSE1属性,就会抛出“类型元素无对应同名列”的错误。
第一步:修复实体与数据库的映射问题
你有三种方案可以解决这个映射不匹配的问题,根据项目约束选择即可:
方案1:直接修改实体属性名(最简单)
如果实体类允许修改,直接把ADRESSE1改成ADRESSE,让它和数据库列名完全一致:
public partial class ADRESSE { public int id { get; set; } public string ADRESSE { get; set; } // 替换原ADRESSE1 public string PERSONAL { get; set; } public string LIEFERADR { get; set; } // 其他属性保持不变 }
方案2:使用数据注解指定列名(无需修改属性名)
如果不能修改实体属性名(比如实体是自动生成的),可以用Column注解明确指定属性对应的数据库列:
using System.ComponentModel.DataAnnotations.Schema; public partial class ADRESSE { public int id { get; set; } [Column("ADRESSE")] // 告诉EF这个属性对应数据库的ADRESSE列 public string ADRESSE1 { get; set; } public string PERSONAL { get; set; } // 其他属性保持不变 }
方案3:用Fluent API配置映射(适合全局配置)
如果项目习惯用Fluent API做EF配置,在DbContext的OnModelCreating方法里添加映射规则:
protected override void OnModelCreating(DbModelBuilder modelBuilder) { // 配置ADRESSE1属性对应数据库的ADRESSE列 modelBuilder.Entity<ADRESSE>() .Property(adresse => adresse.ADRESSE1) .HasColumnName("ADRESSE"); // 其他实体的配置代码... }
第二步:优化动态查询逻辑
你当前的SqlQuery代码只是固定查询所有数据,并没有用到请求头里的参数做过滤。这里给你调整成真正根据请求头参数构建动态查询的版本(同时保证避免SQL注入):
[HttpGet] [AcceptVerbs("GET", "HEAD")] public IQueryable<ADRESSE> GetADRESSE() { var headerParams = HeaderExtractionProvider.GetRequestHeaders(Request.Headers); if (headerParams.Count > 0) { var sqlParams = new List<SqlParameter>(); var whereConditions = new List<string>(); foreach (var param in headerParams) { // 构建参数化查询的条件,避免SQL注入 var paramName = $"@{param[0]}"; whereConditions.Add($"{param[0]} = {paramName}"); sqlParams.Add(new SqlParameter(paramName, param[1])); } // 拼接完整的查询SQL var querySql = $"SELECT * FROM ADRESSE WHERE {string.Join(" AND ", whereConditions)}"; // 执行参数化查询并返回结果 var matchedAdresses = db.ADRESSE.SqlQuery(querySql, sqlParams.ToArray()); return matchedAdresses.AsQueryable(); } // 没有参数时返回所有数据 return db.ADRESSE; }
注意事项
- 确保请求头里的参数名完全匹配数据库表的列名(比如如果请求头传的是
ADRESSE1,那要对应调整成数据库的ADRESSE,或者在循环里做映射); - 用
SqlParameter构建参数化查询可以彻底避免SQL注入风险,不要直接拼接字符串参数。
内容的提问来源于stack exchange,提问作者G. Nah
相关产品推荐
相关产品推荐

