C#中能否创建支持多类型主键列表的泛型数据库控制器类?
在C#中实现支持多类型/多主键的泛型控制器类
你示例中的[Types]<Type>这种动态类型列表的泛型语法在C#中并不直接支持,但可以通过以下几种方案实现类似需求,适配单主键、多主键且类型不同的场景:
方案一:使用元组作为主键类型参数(推荐)
元组可以自然容纳多个不同类型的元素,同时兼容单个类型的场景,是最简洁灵活的实现方式:
public class GenericController<Model, TKey> { public GenericController() { // 获取主键类型的组成部分 var keyTypeArgs = typeof(TKey).GetGenericArguments(); if (keyTypeArgs.Length > 0) { foreach (var type in keyTypeArgs) { Console.WriteLine(type.Name); } } else { // 处理单个非元组类型的主键 Console.WriteLine(typeof(TKey).Name); } } public Model Get(TKey key) { // 替换为实际数据库查询逻辑,比如通过ORM根据主键获取Model return Activator.CreateInstance<Model>(); } }
使用示例
- 单主键(int类型):
var userController = new GenericController<User, int>(); var user = userController.Get(123); - 多主键(int + string类型):
var orderController = new GenericController<Order, (int, string)>(); var order = orderController.Get((456, "ORD001"));
方案二:自定义主键对象+接口约束
如果需要更明确的主键结构定义,可以创建标记接口,让自定义主键类实现该接口,在泛型中做约束:
// 主键标记接口 public interface IEntityKey { } // 单主键实现 public class IntPrimaryKey : IEntityKey { public int Id { get; set; } } // 复合主键实现 public class OrderCompositeKey : IEntityKey { public int OrderId { get; set; } public string CustomerCode { get; set; } } public class GenericController<Model, TKey> where TKey : IEntityKey { public GenericController() { // 遍历主键对象的属性类型 foreach (var prop in typeof(TKey).GetProperties()) { Console.WriteLine(prop.PropertyType.Name); } } public Model Get(TKey key) { // 数据库查询逻辑 return Activator.CreateInstance<Model>(); } }
使用示例
var orderController = new GenericController<Order, OrderCompositeKey>(); var order = orderController.Get(new OrderCompositeKey { OrderId = 789, CustomerCode = "CUST007" });
方案三:方法重载适配不同数量主键
如果主键数量固定(比如最多2-3个),可以通过重载Get方法来实现,不需要额外泛型参数:
public class GenericController<Model> { // 单主键查询 public Model Get<T1>(T1 key1) { Console.WriteLine(typeof(T1).Name); return Activator.CreateInstance<Model>(); } // 双主键查询 public Model Get<T1, T2>(T1 key1, T2 key2) { Console.WriteLine(typeof(T1).Name); Console.WriteLine(typeof(T2).Name); return Activator.CreateInstance<Model>(); } // 可扩展更多主键的重载方法 }
使用示例
var productController = new GenericController<Product>(); // 单主键查询 var product = productController.Get(101); // 双主键查询 var product2 = productController.Get(102, "PROD001");
内容的提问来源于stack exchange,提问作者Skye TheFox
相关产品推荐
相关产品推荐

