实现依赖输入参数类型的泛型输出多表通用数据库查询函数需求
实现依赖输入参数类型的泛型输出多表通用数据库查询函数需求
我太懂这种手动类型转换的麻烦了——不仅每次调用都要写Convert,还容易因为类型不匹配出bug,而且现在要扩展到多表,确实得把这个函数改成更通用的泛型版本。
咱们先拆解下原来的问题:
- 原函数返回
object,必须手动转换类型,不够安全也不简洁 - 只能针对
ConfigTable,没法复用在其他配置表上
下面是改造后的通用泛型方案,完美解决这两个问题:
第一步:重构为泛型多表查询函数
把函数改成支持任意实体表+自动匹配属性类型的泛型方法,利用EF的DbSet<TEntity>来实现多表支持:
public static TResult GetConfigItem<TEntity, TResult>(Func<TEntity, TResult> selector) where TEntity : class { using (var db = new DbContext()) { // 用db.Set<TEntity>()获取任意实体的数据集 var configValue = db.Set<TEntity>().Select(selector).FirstOrDefault(); if (configValue != null) { return configValue; } // 处理null场景:记录日志(这里可以加你的日志逻辑) // Logger.LogWarning($"未找到{typeof(TEntity).Name}中匹配选择器的配置项"); // 返回对应类型的默认值,避免空引用或强制转换错误 return default(TResult); } }
第二步:简化调用方式(无需手动转换)
现在调用的时候,编译器会自动推断泛型参数,直接拿到和属性类型完全一致的返回值,再也不用写Convert了:
// 自动推断为int?类型 var setting1 = GetConfigItem(c => c.Attribuet1); // 自动推断为bool?类型 var setting2 = GetConfigItem(c => c.Attribuet2); // 自动推断为string类型 var setting3 = GetConfigItem(c => c.Attribuet3);
第三步:扩展到其他表
如果有其他配置表,比如OtherConfigTable:
public class OtherConfigTable { [Required, Key] public int Id { get; set; } public decimal? PriceThreshold { get; set; } public DateTime? ExpiryDate { get; set; } }
直接用同一个函数查询,完全不需要额外修改:
// 自动返回decimal?类型 var priceThreshold = GetConfigItem(c => c.PriceThreshold); // 自动返回DateTime?类型 var expiryDate = GetConfigItem(c => c.ExpiryDate);
额外说明
- 关于默认值:因为你的属性都是可空值类型或引用类型,
default(TResult)会返回对应类型的默认值(比如int?的默认是null,string的默认也是null)。如果需要强制返回非空默认值(比如int的0),可以改成return configValue ?? default(TResult);或者针对值类型做特殊处理。 - 泛型推断:大部分情况下编译器能自动识别
TEntity和TResult,所以调用时不用显式指定泛型参数,除非有歧义。
内容来源于stack exchange
相关产品推荐
相关产品推荐

