c# - 调用 EntityTypeBuilder.HasKey 通过反射获得复合键
问题描述
我正在尝试将“历史”表添加到 EFCore,并让它大部分工作。对于我的模型中在类上具有 [Historyable] 属性的每个 POCO,我使用反射生成一个新类,该类除了原始类中的属性之外还具有三个附加属性 - ChangeDate、ChangeType 和 ChangeUserID。
当我需要为新生成的 History 类型设置主键时,我的问题就出现了。在手写代码中,添加主键看起来像:
modelBuilder.Entity<EquipmentPortProfile>().HasKey(k => new { k.Name, k.PortType, k.CardType })
modelBuilder.Entity<EquipmentPortProfileHistory>().HasKey(k => new { k.Name, k.PortType, k.CardType, k.ChangeDate }) // add ChangeDate to keep it unique
其中 EquipmentPortProfile 是我可以手动调用 HasKey() 的原始 [Historable] POCO,EquipmentPortProfileHistory 是我需要通过反射调用 HasKey() 的新生成类型。
我有以下代码,它添加了模型的新 History 类型,但我不太清楚如何使用我构建的 MemberExpressions 列表来一般地调用 HasKey() 。
var type = tbuilder.CreateType(); // create the new History type
var entityMethod = typeof(ModelBuilder).GetMethods().First(f => f.Name == "Entity");
var ent = entityMethod.MakeGenericMethod(type).Invoke(modelBuilder, new object[] { }); // add the new History type to the model
var haskey = ent.GetType().GetMethods().FirstOrDefault(m => m.Name == "HasKey");
var param = Expression.Parameter(type, "k"); List<MemberExpression> args = new List<MemberExpression>();
var pk = historable.FindPrimaryKey();
foreach (var prop in pk.Properties) // we add in the same key properties as the table that we are tracking
args.Add(Expression.PropertyOrField(param, prop.Name));
args.Add(Expression.PropertyOrField(param, "ChangeDate")); // and then also add in ChangeDate as part of the PK to keep it unique
解决方案
最简单的是使用HasKey重载接受params string[] propertyNames
参数。
也不需要Entity<TEntity>
通过反射调用泛型方法,您可以简单地使用非泛型实体方法接受Type type
参数,例如像这样
var type = tbuilder.CreateType(); // create the new History type
var pk = historable.FindPrimaryKey();
var pkPropertyNames = pk.Properties.Select(p => p.Name).Append("ChangeDate").ToArray();
modelBuilder.Entity(type).HasKey(pkPropertyNames);
推荐阅读
- javascript - 自定义元素设置:构造函数与 connectedCallback
- html - 让页脚粘在页面底部并被内容推送
- macos - 如何在 Mac 中安排自动化工作流程
- cassandra - 如何在 Cassandra 中正确配置 CDC
- flutter - 使用 games_services 插件时出错:未处理的异常:PlatformException(error, 4: 4: , null)
- ssl - openssl 命令从 .pfx 文件生成一个空的 .key 文件
- android - 如何在 Espresso 测试中获取视图的标签?
- shell - 使用测试时奇怪的评估结果
- types - 你如何声明一个总和类型/类型联合?
- python - OBS Studio 如何以编程方式设置选项