Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架4通过反射的代码优先继承解决方案_C#_Entity Framework_Reflection_Inheritance_Ef Code First - Fatal编程技术网

C# 实体框架4通过反射的代码优先继承解决方案

C# 实体框架4通过反射的代码优先继承解决方案,c#,entity-framework,reflection,inheritance,ef-code-first,C#,Entity Framework,Reflection,Inheritance,Ef Code First,我已经找到了一些解决这个问题的方法,有些不起作用,有些违反了干燥原则 我想让我的所有实体继承自Audit(它提供属性/列IsActive,CreateDate,UpdateDate,CreateUser,&UpdateUser)。我可以让它正常工作,但这会导致使用关系生成的列名出现问题(CreateUser\u UserId&UpdateUser\u UserId)。我更喜欢CreateUserId和UpdateUserId。不幸的是,ColumnAttribute似乎不像文章那样工作,所以答案

我已经找到了一些解决这个问题的方法,有些不起作用,有些违反了干燥原则

我想让我的所有实体继承自
Audit
(它提供属性/列
IsActive
CreateDate
UpdateDate
CreateUser
,&
UpdateUser
)。我可以让它正常工作,但这会导致使用关系生成的列名出现问题(
CreateUser\u UserId
&
UpdateUser\u UserId
)。我更喜欢
CreateUserId
UpdateUserId
。不幸的是,
ColumnAttribute
似乎不像文章那样工作,所以答案是这样的。然而,fluentapi确实可以工作。它只是因为我创建的每一个实体,我最终都必须这样做:

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);
}

这基本上是我在C#/.Net中做的第一件真实的事情,我觉得它非常复杂。如果我完全错了,请给我一个不适合我的选择。我真的不喜欢T4模板或接口的想法-这是我不想维护的重复代码。

是审计实体本身吗?如果是,您可以直接在审计中应用这些规则

我还认为使用继承是不好的。我将使用复杂类型属性。见:


为什么要更改DB模式的生成方式。特别是首先使用代码,这应该是隐藏的。我看到改变这个的唯一原因是当您已经有了DB模式并且想要为它创建映射时。

是审计实体本身吗?如果是,您可以直接在审计中应用这些规则

我还认为使用继承是不好的。我将使用复杂类型属性。见:

为什么要更改DB模式的生成方式。特别是首先使用代码,这应该是隐藏的。我看到更改此方法的唯一原因是当您已经有了DB schema并希望为其创建映射时。

创建帮助器方法:

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); 
}
创建辅助对象方法:

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); 
}

这很有魅力!我创建了
MapUserRelations
static
,相应地更改了
BindingFlags
,并将
OnModelCreating
的主体重构为另一个静态方法(如我所想,我将向
OnModelCreating
的主体添加更多内容)。我不知道这是否应该是一个单独的问题-我如何才能使
“MapUserRelations”
编译安全?@Olson:糟糕。反射不是编译安全的。什么是“糟糕的”。关于它?我说的编译安全,是指。。是否有任何语法可以有效地生成字符串
“MapUserRelations”
?类似(伪语法)
MyClass.MapUserRelations.ToString()
…?这就像一个符咒!我创建了
MapUserRelations
static
,相应地更改了
BindingFlags
,并将
OnModelCreating
的主体重构为另一个静态方法(如我所想,我将向
OnModelCreating
的主体添加更多内容)。我不知道这是否应该是一个单独的问题-我如何才能使
“MapUserRelations”
编译安全?@Olson:糟糕。反射不是编译安全的。什么是“糟糕的”。关于它?我说的编译安全,是指。。是否有任何语法可以有效地生成字符串
“MapUserRelations”
?类似于(伪语法)
MyClass.MapUserRelations.ToString()
…?+1的建议。不,
审核
本身不是一个实体。我浏览了你链接到的那篇文章——虽然复杂类型很好(我可能会改变我的模型使用复杂类型),但我最终还是得到了不太理想的列名。我想改变模式生成的方式,因为无论我喜欢与否,人们(包括我自己)都必须手动触摸这些列(有些事情在数据库层上更容易)。另外,覆盖它们在UI中的显示方式将更容易/更一致。建议+1。不,
审核
本身不是一个实体。我浏览了你链接到的那篇文章——虽然复杂类型很好(我可能会改变我的模型使用复杂类型),但我最终还是得到了不太理想的列名。我想改变模式生成的方式,因为无论我喜欢与否,人们(包括我自己)都必须手动触摸这些列(有些事情在数据库层上更容易)。另外,覆盖它们在UI中的显示方式将更容易/更一致。
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 });
    }
}