在EF Core中设置属性约定?

时间:2018-10-03 14:31:07

标签: c# entity-framework asp.net-core entity-framework-core

在NHibernate中,他们有一个约定的漂亮小概念,您可以说,如果实体具有Name属性,并且它是字符串,则可以对其应用某些db行为(例如,将其设置为非null,最大长度x,如果可以确定所有名称都是唯一的,则可以唯一。)

这将是一个小类,您需要将其添加到实例工厂中,然后开始! db模型将相应地构建。

EF Core中是否有类似的机制?我似乎找不到任何东西,而且对于每个实体,每个属性的流利配置数量都非常可笑。

1 个答案:

答案 0 :(得分:3)

在EF Core中,内置约定用于创建初始模型,您可以在OnModelCreating中覆盖或修改初始模型。

您可以简单地遍历您的实体,并且属性将覆盖约定。这足以代替EF6的自定义约定,(至少到目前为止)自定义约定还没有积压。有关状态和一些示例,请参见https://github.com/aspnet/EntityFrameworkCore/issues/214。在OnModelCreating中读取自定义属性以驱动(或覆盖)您的实体配置也是一种很常见的模式。

所以你的例子:

  

如果实体具有Name属性,并且它是一个字符串,则可以对其应用某些db行为(例如,将其设置为not null,最大长度x,如果可以确定所有名称都可以是唯一的)唯一)。

应该是这样的:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        var props = from e in modelBuilder.Model.GetEntityTypes()
                    from p in e.GetProperties()
                    where p.Name == "Name"
                       && p.PropertyInfo.PropertyType == typeof(string)
                    select p;

        foreach (var p in props)
        {
            p.SetMaxLength(200);
            p.IsNullable = false;
            p.DeclaringEntityType.AddKey(p);
        }

        base.OnModelCreating(modelBuilder);
    }

或者,如果您想对所有DataTime列强制使用数据类型,则类似:

    var dateProps = from e in modelBuilder.Model.GetEntityTypes()
                from p in e.GetProperties()
                where p.PropertyInfo.PropertyType == typeof(DateTime)
                select p;
    foreach (var prop in dateProps)
    {
        prop.Relational().ColumnType = "datetime2(4)";

    }