首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于反射的实体框架4代码优先继承解决方案

基于反射的实体框架4代码优先继承解决方案
EN

Stack Overflow用户
提问于 2011-04-02 13:01:16
回答 2查看 1.1K关注 0票数 0

我已经找到了这个问题的几个解决方案,有些不起作用,有些违反了DRY原则。

我希望我的所有实体都继承自Audit (它提供了属性/列IsActiveCreateDateUpdateDateCreateUserUpdateUser)。我可以让它工作得很好,但这会给使用关系(CreateUser_UserId & UpdateUser_UserId)生成的列名带来问题。我更喜欢CreateUserIdUpdateUserId。不幸的是,ColumnAttribute似乎并不像文章/答案所说的那样工作。但是,Fluent API确实可以工作。它违反了DRY,因为我创建的每一个实体,我最终不得不做这样的事情:

代码语言:javascript
复制
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上有效地调用这些方法链。这是在我完全被难住之前,我从搜索中得到的结果:

代码语言:javascript
复制
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模板或接口的想法--这些都是我不想维护的重复代码。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-04-02 18:49:54

创建帮助器方法:

代码语言:javascript
复制
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); 
}

并使用你的反射:

代码语言:javascript
复制
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 });
    }
}
票数 3
EN

Stack Overflow用户

发布于 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模式,并且想要为它创建映射。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5521283

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档