user610217
user610217

Reputation:

Set Property Conventions in EF Core?

In NHibernate they had a nifty little concept of a convention, where you could say, if an entity had a Name property, and it was a string, you could apply certain db behavior to it (for example, set it to not null, max length x, maybe unique if you could be certain all names would be unique).

It would be a small class, you'd add it to your instance factory, and bam! The db model would build accordingly.

Is there a comparable mechanism in EF Core? I can't seem to find any and the ridiculous number of fluent configurations for every entity for every property is quite tedious.

Upvotes: 5

Views: 4253

Answers (1)

David Browne - Microsoft
David Browne - Microsoft

Reputation: 89091

In EF Core the built-in conventions are used to create an initial model, which you can override or modify in OnModelCreating.

You can simply iterate over your entities and properties override the conventions. This works well enough in place of custom conventions from EF6 that (at least so far) custom conventions haven't made it off the backlog. See https://github.com/aspnet/EntityFrameworkCore/issues/214 for status and some examples. It's also a pretty common pattern to read a custom attribute in OnModelCreating to drive (or override) your entity configuration.

So your example:

if an entity had a Name property, and it was a string, you could apply certain db behavior to it (for example, set it to not null, max length x, maybe unique if you could be certain all names would be unique).

would be something like:

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

Or if you wanted to force the datatypes for all DataTime columns, something like:

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

    }

Upvotes: 12

Related Questions