I'm attempting to add "History" tables to EFCore, and have it mostly working. For every POCO in my model that has a [Historyable] attribute on the class, I use reflection to generate a new class that has three additional properties in addition to the properties that are in the original class - ChangeDate, ChangeType, and ChangeUserID.
My problem comes when I need to set the primary key for the new generated History type. In hand written code, adding the primary keys would look something like:
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
where EquipmentPortProfile is the original [Historable] POCO that I can manually call HasKey() for and EquipmentPortProfileHistory is the new generated type that I need to call HasKey() for via reflection.
I've got the following code which adds the new History type of the model, but I can't quite figure out how to generically invoke the call to HasKey() with the List of MemberExpressions I've built.
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
Aucun commentaire:
Enregistrer un commentaire