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

Mac*_*cko 16 c# entity-framework-core

使用EF 6.1+时,我们需要添加或删除现有的conentions.代码看起来或多或少像:

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);
            }
}
Run Code Online (Sandbox Code Playgroud)

如何在EF核心中做到这一点?Modelbuilder没有会议特性:(

Pau*_*her 14

我正在将一些代码从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);
    }
}
Run Code Online (Sandbox Code Playgroud)

例如,使用这些可以编写类似于EF 6.1.x中的约定.

// equivalent of modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.EntityTypes()
            .Configure(et => et.Relational().TableName = et.DisplayName());

// Put the table name on the primary key
modelBuilder.Properties()
            .Where(x => x.Name == "Id")
            .Configure(p => p.Relational().ColumnName = p.DeclaringEntityType.Name + "Id");

// Mark timestamp columns as concurrency tokens
modelBuilder.Properties()
            .Where(x => x.Name == "Timestamp")
            .Configure(p => p.IsConcurrencyToken = true);
Run Code Online (Sandbox Code Playgroud)

没有检查这个效率,但除非你的模型很大,否则不应该造成问题

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


Bal*_*lah 10

看起来它仍然没有在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);
}
Run Code Online (Sandbox Code Playgroud)

你应该可以做很多事情 entityType