Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.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
Entity framework 实体框架截获生成迁移脚本_Entity Framework_Entity Framework 6_Entity Framework Migrations - Fatal编程技术网

Entity framework 实体框架截获生成迁移脚本

Entity framework 实体框架截获生成迁移脚本,entity-framework,entity-framework-6,entity-framework-migrations,Entity Framework,Entity Framework 6,Entity Framework Migrations,我首先使用EntityFramework6.2代码(.NETFramework 4.6.1),并通过表属性映射少数实体以查看。它适用于select操作,我使用写入触发器在sql server端处理Insert/Update/Delete。它按预期工作,但当我添加新迁移时,Entity Framework会为已使用的表属性生成可重命名脚本(实际上是EF的预期行为)。但我想拦截迁移生成并将这些实体的tableName更改为原始名称 我的代码像 [MapToView("Users","UsersVie

我首先使用EntityFramework6.2代码(.NETFramework 4.6.1),并通过表属性映射少数实体以查看。它适用于select操作,我使用写入触发器在sql server端处理Insert/Update/Delete。它按预期工作,但当我添加新迁移时,Entity Framework会为已使用的表属性生成可重命名脚本(实际上是EF的预期行为)。但我想拦截迁移生成并将这些实体的tableName更改为原始名称

我的代码像

[MapToView("Users","UsersView")]
public class User
{
...
}
我编写了MapToView属性,该属性由TableAttribute继承,并传递给TableAttribute的第二个参数。我之所以创建这个属性,是因为如果我截获迁移生成,就用这个属性参数返回原始表名

在本例中,当我运行“AddMigrationName”时,它会创建如下迁移脚本:

RenameTable(name: "dbo.Users", newName: "UsersView");
protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            var typesToRegister = Assembly.GetExecutingAssembly()
                .GetTypes().Where(IsConfigurationType);

            foreach (var type in typesToRegister)
            {
                dynamic configurationInstance = type.BaseType != null
                                                && type.BaseType.IsGenericType
                                                && type.BaseType.GetGenericTypeDefinition() == typeof(BaseEntityConfiguration<>)
                    ? Activator.CreateInstance(type, culture)
                    : Activator.CreateInstance(type);

                modelBuilder.Configurations.Add(configurationInstance);
            }

            modelBuilder.Types().Configure(t => t.ToTable(t.ClrType.Name));
            BaseDbContext.InternalModelCreate(modelBuilder);
        }
但我想在运行“AddMigrationName”脚本时创建空迁移

有人能帮我吗?

我解决了这个问题。 第一:问题是;当我将实体映射到视图时,EF代码首先使用ViewName生成迁移。这是一个问题,因为我想使用视图而不是表。所以我用这个指令来解决问题

1-我创建从EntityTypeConfiguration继承的BaseEntityConfiguration,所有实体配置类都由继承。 例如:

public class UserConfig: BaseEntityConfiguration<User> //Generic Type is Entity
    {
        public UserConfig()
        {
        }
    }
3-我使用MapToViewAttribute作为示例用户实体来使用视图

 [MapToView("User","UserView")]
    public class User
    {
      ...
    }
在BaseEntityConfiguration的构造函数中,我得到了泛型类型和自定义属性。若任何实体具有MapToView属性,我将TableName参数传递给ToTable方法。因此,在运行时,EF对这些实体使用View,但不为这些实体创建带有RenameTable的迁移

protected BaseEntityConfiguration()
        {
            var baseType = typeof(TEntityType);
            var attributes = baseType.GetCustomAttributes(true);
            foreach (var attr in attributes)
            {
                if (attr.GetType() == typeof(MapToViewAttribute))
                {
                    var tableName = ((MapToViewAttribute)attr).TableName;
                    ToTable(tableName);
                }
            }
        }
最后一个EF不使用您的配置文件,所以您必须告诉EF在DbContext类的InternalModelCreate方法中使用它。 我的实现是这样的

RenameTable(name: "dbo.Users", newName: "UsersView");
protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            var typesToRegister = Assembly.GetExecutingAssembly()
                .GetTypes().Where(IsConfigurationType);

            foreach (var type in typesToRegister)
            {
                dynamic configurationInstance = type.BaseType != null
                                                && type.BaseType.IsGenericType
                                                && type.BaseType.GetGenericTypeDefinition() == typeof(BaseEntityConfiguration<>)
                    ? Activator.CreateInstance(type, culture)
                    : Activator.CreateInstance(type);

                modelBuilder.Configurations.Add(configurationInstance);
            }

            modelBuilder.Types().Configure(t => t.ToTable(t.ClrType.Name));
            BaseDbContext.InternalModelCreate(modelBuilder);
        }
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
var typesToRegister=Assembly.getExecutionGassembly()
.GetTypes().Where(isConfiguration类型);
foreach(TypeStoreRegister中的变量类型)
{
动态配置实例=type.BaseType!=null
&&type.BaseType.IsGenericType
&&type.BaseType.GetGenericTypeDefinition()==typeof(BaseEntityConfiguration)
?Activator.CreateInstance(类型、区域性)
:Activator.CreateInstance(类型);
modelBuilder.Configurations.Add(configurationInstance);
}
modelBuilder.Types().Configure(t=>t.ToTable(t.ClrType.Name));
BasedContext.InternalModelCreate(modelBuilder);
}
但如果使用这种方法,则必须创建插入、更新和删除触发器/规则(如果使用SQLServer触发器是一个选项,但如果使用postgresql规则则更好),因为EF使用此视图进行插入、更新和删除操作。

我解决了这个问题。 第一:问题是;当我将实体映射到视图时,EF代码首先使用ViewName生成迁移。这是一个问题,因为我想使用视图而不是表。所以我用这个指令来解决问题

1-我创建从EntityTypeConfiguration继承的BaseEntityConfiguration,所有实体配置类都由继承。 例如:

public class UserConfig: BaseEntityConfiguration<User> //Generic Type is Entity
    {
        public UserConfig()
        {
        }
    }
3-我使用MapToViewAttribute作为示例用户实体来使用视图

 [MapToView("User","UserView")]
    public class User
    {
      ...
    }
在BaseEntityConfiguration的构造函数中,我得到了泛型类型和自定义属性。若任何实体具有MapToView属性,我将TableName参数传递给ToTable方法。因此,在运行时,EF对这些实体使用View,但不为这些实体创建带有RenameTable的迁移

protected BaseEntityConfiguration()
        {
            var baseType = typeof(TEntityType);
            var attributes = baseType.GetCustomAttributes(true);
            foreach (var attr in attributes)
            {
                if (attr.GetType() == typeof(MapToViewAttribute))
                {
                    var tableName = ((MapToViewAttribute)attr).TableName;
                    ToTable(tableName);
                }
            }
        }
最后一个EF不使用您的配置文件,所以您必须告诉EF在DbContext类的InternalModelCreate方法中使用它。 我的实现是这样的

RenameTable(name: "dbo.Users", newName: "UsersView");
protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            var typesToRegister = Assembly.GetExecutingAssembly()
                .GetTypes().Where(IsConfigurationType);

            foreach (var type in typesToRegister)
            {
                dynamic configurationInstance = type.BaseType != null
                                                && type.BaseType.IsGenericType
                                                && type.BaseType.GetGenericTypeDefinition() == typeof(BaseEntityConfiguration<>)
                    ? Activator.CreateInstance(type, culture)
                    : Activator.CreateInstance(type);

                modelBuilder.Configurations.Add(configurationInstance);
            }

            modelBuilder.Types().Configure(t => t.ToTable(t.ClrType.Name));
            BaseDbContext.InternalModelCreate(modelBuilder);
        }
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
var typesToRegister=Assembly.getExecutionGassembly()
.GetTypes().Where(isConfiguration类型);
foreach(TypeStoreRegister中的变量类型)
{
动态配置实例=type.BaseType!=null
&&type.BaseType.IsGenericType
&&type.BaseType.GetGenericTypeDefinition()==typeof(BaseEntityConfiguration)
?Activator.CreateInstance(类型、区域性)
:Activator.CreateInstance(类型);
modelBuilder.Configurations.Add(configurationInstance);
}
modelBuilder.Types().Configure(t=>t.ToTable(t.ClrType.Name));
BasedContext.InternalModelCreate(modelBuilder);
}

但如果使用这种方法,则必须创建插入、更新和删除触发器/规则(如果使用SQLServer触发器是一个选项,但如果使用postgresql规则则更好),因为EF使用此视图进行插入、更新和删除操作。

使用视图而没有数据库优先工作流是不寻常的。是的,我知道,但我需要它。因为我必须从视图中获取数据,但必须在实表中执行插入、更新或删除操作。所以我使用Table属性将表名更改为view,但这次insert、update和delete查询也映射到view,然后我为它们编写了触发器,但我不知道如何拦截ef生成迁移,以及如何将表名视图更改为迁移脚本的实表名。对。所以我建议您停止使用迁移。而是直接管理数据库模式,切换到数据库优先工作流。您好@DavidBrowne Microsoft I解决问题并发布答案。我知道这不是一个有效的方法,但它是有效的。谢谢你的推荐。使用视图而没有数据库是很少见的