Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.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# 实体框架的核心约定在哪里?_C#_Entity Framework Core - Fatal编程技术网

C# 实体框架的核心约定在哪里?

C# 实体框架的核心约定在哪里?,c#,entity-framework-core,C#,Entity Framework Core,使用EF 6.1+时,有时我们需要添加或删除现有约束。代码大致如下所示: public class MyContext : DbContext { protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Conventions.AddFromAssembly(Assembly.GetExecutin

使用EF 6.1+时,有时我们需要添加或删除现有约束。代码大致如下所示:

public class MyContext : DbContext
    {
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                modelBuilder.Conventions.AddFromAssembly(Assembly.GetExecutingAssembly());
                modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
                modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
                modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();

                base.OnModelCreating(modelBuilder);
            }
}
公共类MyContext:DbContext
{
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.AddFromAssembly(Assembly.getExecutionGassembly());
modelBuilder.Conventions.Remove();
modelBuilder.Conventions.Remove();
modelBuilder.Conventions.Remove();
基于模型创建(modelBuilder);
}
}

如何在EF core中实现同样的功能?Modelbuilder没有Conventions属性:(

看起来它仍然不在EF Core 2.0中。因此,这里有一种实现它的方法。我这样做是为了对某些属性应用一致的行为,但为了解决您问题中的示例,您可以尝试以下方法:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    // equivalent of modelBuilder.Conventions.AddFromAssembly(Assembly.GetExecutingAssembly());
    // look at this answer: https://stackoverflow.com/a/43075152/3419825

    // for the other conventions, we do a metadata model loop
    foreach (var entityType in modelBuilder.Model.GetEntityTypes())
    {
        // equivalent of modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        entityType.Relational().TableName = entityType.DisplayName();

        // equivalent of modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
        // and modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
        entityType.GetForeignKeys()
            .Where(fk => !fk.IsOwnership && fk.DeleteBehavior == DeleteBehavior.Cascade)
            .ToList()
            .ForEach(fk => fk.DeleteBehavior = DeleteBehavior.Restrict);
    }

    base.OnModelCreating(modelBuilder);
}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
//等效于modelBuilder.Conventions.AddFromAssembly(Assembly.getExecutionGassembly());
//看看这个答案:https://stackoverflow.com/a/43075152/3419825
//对于其他约定,我们执行元数据模型循环
foreach(modelBuilder.Model.GetEntityTypes()中的var entityType)
{
//与modelBuilder.Conventions.Remove()等效;
entityType.Relational().TableName=entityType.DisplayName();
//与modelBuilder.Conventions.Remove()等效;
//和modelBuilder.Conventions.Remove();
entityType.GetForeignKeys()
.Where(fk=>!fk.isoownership&&fk.DeleteBehavior==DeleteBehavior.Cascade)
托利斯先生()
.ForEach(fk=>fk.DeleteBehavior=DeleteBehavior.Restrict);
}
基于模型创建(modelBuilder);
}

您应该能够使用entityType做很多事情,我正在将一些代码从EF移植到EF Core 2.1+,迫不及待地等待EF Core 3.0,因此编写了一些扩展方法,这些方法对您有所帮助

public static IEnumerable<IMutableEntityType> EntityTypes(this ModelBuilder builder)
{
    return builder.Model.GetEntityTypes();
}

public static IEnumerable<IMutableProperty> Properties(this ModelBuilder builder)
{
    return builder.EntityTypes().SelectMany(entityType => entityType.GetProperties());
}

public static IEnumerable<IMutableProperty> Properties<T>(this ModelBuilder builder)
{
    return builder.EntityTypes().SelectMany(entityType => entityType.GetProperties().Where(x => x.ClrType == typeof(T)));
}

public static void Configure(this IEnumerable<IMutableEntityType> entityTypes, Action<IMutableEntityType> convention)
{
    foreach (var entityType in entityTypes)
    {
        convention(entityType);
    }
}

public static void Configure(this IEnumerable<IMutableProperty> propertyTypes, Action<IMutableProperty> convention)
{
    foreach (var propertyType in propertyTypes)
    {
        convention(propertyType);
    }
}
我还没有检查过它的效率,但是除非你的模型很大,否则它不会造成问题


这可以通过外键、索引等的其他帮助程序进行扩展

为了在EF Core 5中设置单数表名,您可以执行以下操作

modelBuilder.Model.GetEntityTypes()            
    .Configure(et => et.SetTableName(et.DisplayName()));
但是,如果域中有值对象,它们都将被视为实体类型,并在数据库中创建为表。如果值对象都继承自基本类型,如
ValueObject
,则可以使用以下方法:

modelBuilder.Model.GetEntityTypes()            
    .Where(x => !x.ClrType.IsSubclassOf(typeof(ValueObject)))
    .Configure(et => et.SetTableName(et.DisplayName()));
EF Core 5的另一个缺点是,当您在实体模型中使用继承时,设置表名会从(TPH)更改为(TPT)

您可以使用以下替代方法(假设您的实体源自
BaseEntity


实体框架核心约定在哪里?在未来的某个地方(检查EF核心路线图和积压工作)。计划在3.0版本中使用,请参见.NET Core 3.1——EF Core 5和单复数表名约定请参见此处entityType.Relational().TableName=entityType.DisplayName();如果entityType是“owned”类型,则可能很危险。如果entityType是“owned”类型,则DisplayName()返回所有者表名。这将打乱数据库设计和迁移脚本。@thomasgalliker找到解决方案了吗?同时,我只筛选IsOwned()类型==真。请看一下这行代码:它是否存在于.net core 3.1中?当我尝试执行此操作时,Getting
“IEnumerable”不包含“Configure”的定义。
modelBuilder.Model.GetEntityTypes()            
    .Configure(et => et.SetTableName(et.DisplayName()));
modelBuilder.Model.GetEntityTypes()            
    .Where(x => !x.ClrType.IsSubclassOf(typeof(ValueObject)))
    .Configure(et => et.SetTableName(et.DisplayName()));
modelBuilder.Model.GetEntityTypes()
    .Where(x => x.ClrType.BaseType == typeof(BaseEntity))
    .Configure(et => et.SetTableName(et.DisplayName()));