Set Property Conventions in EF Core?

asp.net-core c# entity-framework entity-framework-core

Question

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.

1
1
10/3/2018 2:31:07 PM

Accepted Answer

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

    }
3
3/26/2019 12:36:41 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow