Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support single configuration for all uses of an owned type, shared type, or some arbitrary base class/interface #6787

Open
Tracked by #22952
arruw opened this issue Oct 15, 2016 · 11 comments

Comments

@arruw
Copy link

arruw commented Oct 15, 2016

Previous non core version of Entity Framework had something like this:

modelBuilder.Type<IEntity>().HasKey(e => e.Id);

I'm curious if this is planned for core version to?

I tried to implement something similar with reflection. https://gist.github.com/matjazmav/2e7335c12c55c4f6692b637bccf651bb There is only one problem with this implementation, casting object to EntityModelBuilder<TEntity> (this is marked with // TODO in the gist snippet). Anyone wan't to help me solve this?

Thanks!

@rowanmiller
Copy link
Contributor

rowanmiller commented Oct 17, 2016

We don't have the equivalent functionality in EF Core yet, but you can write something like this (less pretty, but does the same thing).

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    foreach (var entity in modelBuilder.Model.GetEntityTypes().Where(e => typeof(IEntity).IsAssignableFrom(e.ClrType)))
    {
        modelBuilder.Entity(entity.Name).HasKey(nameof(IEntity.Key));
    }
}

@rowanmiller rowanmiller changed the title Configure base class and/or interface of entity with Fluent API and reflection. Modeling: Bulk configuration based on unmapped base types Oct 24, 2016
@rowanmiller rowanmiller added this to the 1.2.0 milestone Oct 24, 2016
@rowanmiller rowanmiller changed the title Modeling: Bulk configuration based on unmapped base types Model Definition: Bulk configuration based on unmapped base types Oct 24, 2016
@AndriySvyryd
Copy link
Member

AndriySvyryd commented Apr 13, 2017

With this modelBuilder.Owned<>() would be obsolete.

Related to #3867
Superseeds #14047

@chrispickford
Copy link

The workaround mentioned above doesn't seem to be working for inherited property definitions. I have the following statement in my OnModelCreating():

foreach (var entity in modelBuilder.Model.GetEntityTypes()
  .Where(e => typeof(IEntity).IsAssignableFrom(e.ClrType)))
{
  modelBuilder.Entity(entity.Name).Property(nameof(IEntity.Uuid))
    .IsRequired().HasDefaultValueSql("NEWID()");
}

I'd expect this produce the following line in the migration for each IEntity, but it does not:

Uuid = table.Column<Guid>(nullable: false, defaultValueSql: "NEWID()")

@ajcvickers
Copy link
Member

@chrispickford It works for me in a simple test:

public interface IEntity
{
    Guid Id { get; set; }
}

public class Vehicle : IEntity
{
    public Guid Id { get; set; }
    public string VehicleIdentificationNumber { get; set; }
}

public class VehiclePrototype : IEntity
{
    public Guid Id { get; set; }
    public DateTimeOffset? PressReleaseAt { get; set; }
}

public class BloggingContext : DbContext
{
    private static readonly LoggerFactory Logger
        = new LoggerFactory(new[] { new ConsoleLoggerProvider((_, __) => true, true) });

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        => optionsBuilder
            .UseLoggerFactory(Logger)
            .UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Test;ConnectRetryCount=0");

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Vehicle>();
        modelBuilder.Entity<VehiclePrototype>();

        foreach (var entity in modelBuilder.Model.GetEntityTypes()
            .Where(e => typeof(IEntity).IsAssignableFrom(e.ClrType)))
        {
            modelBuilder.Entity(entity.Name).Property(nameof(IEntity.Id))
                .IsRequired().HasDefaultValueSql("NEWID()");
        }
    }
}

public class Program
{
    public static async Task Main()
    {
        using (var context = new BloggingContext())
        {
            await context.Database.EnsureDeletedAsync();
            await context.Database.EnsureCreatedAsync();

            context.Add(new Vehicle());
            context.Add(new VehiclePrototype());
            context.SaveChanges();
        }
    }
}

@chrispickford
Copy link

@ajcvickers Apologies, in my haste I constructed an incorrect example. The IEntity should be an abstract class, e.g:

public abstract class Entity
{
  public int Id { get; set; }
  public byte[] RowVersion { get; set; }
  public Guid Uuid { get; set; }
}

@ajcvickers
Copy link
Member

@chrispickford Still works for me. Can you please file a new issue including a runnable project/solution or complete code listing that demonstrates the behavior you are seeing.

@ajcvickers ajcvickers reopened this Oct 1, 2018
@ajcvickers ajcvickers changed the title Model Definition: Bulk configuration based on unmapped base types Model Definition: Bulk configuration based on un-mapped base types or interfaces Aug 26, 2019
@ajcvickers
Copy link
Member

Consider also query filters--see #17434

@ajcvickers ajcvickers changed the title Model Definition: Bulk configuration based on un-mapped base types or interfaces Support single configuration for all uses of an owned type, shared type, or some arbitrary base class/interface Jul 24, 2020
@visschersm
Copy link

Previous non core version of Entity Framework had something like this:

modelBuilder.Type<IEntity>().HasKey(e => e.Id);

I'm curious if this is planned for core version to?

I tried to implement something similar with reflection. https://gist.github.com/matjazmav/2e7335c12c55c4f6692b637bccf651bb There is only one problem with this implementation, casting object to EntityModelBuilder<TEntity> (this is marked with // TODO in the gist snippet). Anyone wan't to help me solve this?

Thanks!

Would really love to see this, are there any current plans to implement this a future version of EFCore?
Or are there new ways in EFCore 5 that I can use to get to the same result?

Currently using reflection to configure my interface derived entities, but like the Framework interface configuration way more.

@ajcvickers
Copy link
Member

@visschersm This issue is in the Backlog milestone. This means that it is not planned for the next release (EF Core 6.0). We will re-assess the backlog following the this release and consider this item at that time. However, keep in mind that there are many other high priority features with which it will be competing for resources.

@AndriySvyryd
Copy link
Member

Proposed API design: #12229 (comment)

@ajcvickers
Copy link
Member

Consider query filters when working on this. See #10257.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants