我已经找到了这个问题的几个解决方案,有些不起作用,有些违反了DRY原则。
我希望我的所有实体都继承自Audit (它提供了属性/列IsActive、CreateDate、UpdateDate、CreateUser和UpdateUser)。我可以让它工作得很好,但这会给使用关系(CreateUser_UserId & UpdateUser_UserId)生成的列名带来问题。我更喜欢CreateUserId和UpdateUserId。不幸的是,ColumnAttribute似乎并不像文章/答案所说的那样工作。但是,Fluent API确实可以工作。它违反了DRY,因为我创建的每一个实体,我最终不得不做这样的事情:
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
// have to write these two lines for each new entity I create
modelBuilder.Entity<User>().HasOptional(u => u.CreateUser).WithMany().HasForeignKey(u => u.CreateUserId).WillCascadeOnDelete(false);
modelBuilder.Entity<User>().HasOptional(u => u.UpdateUser).WithMany().HasForeignKey(u => u.UpdateUserId).WillCascadeOnDelete(false);
}因此,我想使用反射遍历每个扩展Audit的类型,并在我的modelBuilder上有效地调用这些方法链。这是在我完全被难住之前,我从搜索中得到的结果:
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
var types = GetTypesInheritingFrom(typeof (Audit)); // implementation unimportant
foreach (var t in types) {
var method = modelBuilder.GetType().GetMethod("Entity");
var generic = method.MakeGenericMethod(t);
var o = generic.Invoke(modelBuilder, null);
// not sure how to proceed from here, HasOptional() requires an Expression<Func<t, TTargetEntity>>
// not sure if WithMany() is actually required??
// not sure what to do with HasForeignKey() either, it requires an Expression<Func<User, Guid>>
}
}这基本上是我用C#/.Net做的第一件真正的事情,对我来说感觉真的很复杂。如果我的方法完全错误,请给我一个不适合我的替代方案。我真的不喜欢T4模板或接口的想法--这些都是我不想维护的重复代码。
发布于 2011-04-02 18:49:54
创建帮助器方法:
private void MapUserRelations<TEntity>(DbModelBuilder modelBuilder)
where TEntity : Audit
{
modelBuilder.Entity<TEntity>().HasOptional(u => u.CreateUser).WithMany().HasForeignKey(u => u.CreateUserId).WillCascadeOnDelete(false);
modelBuilder.Entity<TEntity>().HasOptional(u => u.UpdateUser).WithMany().HasForeignKey(u => u.UpdateUserId).WillCascadeOnDelete(false);
}并使用你的反射:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
var types = GetTypesInheritingFrom(typeof (Audit));
foreach (var t in types)
{
var method = this.GetType().GetMethod("MapUserRelations");
var generic = method.MakeGenericMethod(t, BindingFlags.NonPublic | BindingFlags.Instance);
generic.Invoke(this, new Object[] { modelBuilder });
}
}发布于 2011-04-02 18:37:43
是审计实体本身吗?如果是,您可以直接在Audit上应用这些规则。
我也认为使用继承是不好的。我会使用复杂类型属性来代替。请参阅:http://weblogs.asp.net/manavi/archive/2011/03/28/associations-in-ef-4-1-code-first-part-2-complex-types.aspx
为什么要更改DB模式的生成方式。特别是先使用代码,这应该是隐藏的。我认为需要更改它的唯一原因是您已经有了DB模式,并且想要为它创建映射。
https://stackoverflow.com/questions/5521283
复制相似问题