-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
Model configuration: Entity type configuration can be factored into a class #2805
Comments
EntityTypeConfiguration<T>
in EF 7?
You can configure the mapping by overriding |
So if we have complex mappings, we just need to factor out into our own static classes and call them from OnModelCreating. This will need to suffice for the primary use case for EntityTypeConfiguration in EF6. |
There are several ways of factoring
into
or
|
It would be really great to have something like EntityTypeConfiguration and also with autoscanning like in FluentNHibernate. |
Reopening so that we can triage this... we should consider enabling the same pattern we had in EF6. It's trivial to implement it yourself... but it is a nice piece of sugar that we've seen numerous people use. |
I'm glad I'm not the only one. I rely on it heavily. I've actually started a solution that I can probably contribute back. |
Moving to backlog since it's not critical for our initial release (it's very easy to quickly implement this yourself without needing to modify EF code). That said, we do want to implement it and we would accept a PR for it. |
@mmillican Do you have anything available already? I require the functionality of being able to specify entity type configurations, too. However, I won't have access to a concrete DbContext implementation to access OnModelCreating (this issue has been persistent throughout EF releases, requiring proxying to get around), as the DbContext is generated on-the-fly with assembly scanning. I would implement an IModelSource, but individual implementations of providers have their own modelsource which they request on model creation. One of the solutions I can see, is adding an two interfaces: public interface IModelBuilderContributor
{
void Contribute(ModelBuilder modelBuilder);
}
public interface IModelBuilderContributorSource
{
IEnumerable<IModelBuilderContributor> GetContributors([NotNull] DbContext context);
} and extend parameters of IModelSource => GetModel() and ModelSource => CreateModel() with if (contributorSource != null)
ContributeToModelBuilder(modelBuilder, contributorSource.GetContributors(context));
protected virtual void ContributeToModelBuilder(ModelBuilder modelBuilder, IEnumerable<IModelBuilderContributor> getContributors)
{
foreach(var contributor in getContributors)
contributor.Contribute(modelBuilder);
} finally add to DbContextServices constructor private variable assignment _modelBuilderContributorSource =
new LazyRef<IModelBuilderContributorSource>(
() => _provider.GetRequiredService<IModelBuilderContributorSource>()); This would give "infinite extension points!", as contributors would come through DbContext's own serviceprovider, have the capability for DI, and would allow any arbitrary additional extension points (such as If this is something that would be even wildly acceptable in EF7 (rather than hardwiring the responsibility of adding type configurations in OnModelCreating override), and is not already worked on, I'm more than willing to implement and PR. |
@Grinderofl - I haven’t yet, unfortunately; I got tied up in projects. It is still on my list however. My use case is similar to yours, in that I use assembly scanning to add types to the context. This is extremely useful for large applications as well as “plugin” style applications. I think I follow what you are saying with your ideas, and they make sense. My idea was to essentially replicate the |
Okay, I'll attempt to implement it and pr, got some rough stubs in place now. |
#2992 describes a mechanism that could be used to implement this. |
This is still required, unfortunately due to time constraints I had to go ahead and implement the ability to configure dbcontext programmatically via https://github.com/Grinderofl/FluentModelBuilder instead of PRing, though truly, all that is needed, is to expose ModelBuilder somewhere outside of DbContext.OnModelCreating(). |
Removing |
@valmont EF Core is still trying to focus on simplicity first, which means that there's a mechanism to support any kind of model customization - IModelCustomizer (implement/override ModelCustomizer, replace in services after AddEntityFramework()) I've written a library to make that a bit easier if you are interested. https://github.com/Grinderofl/FluentModelBuilder |
Use:
|
So is EntityTypeConfiguration class (and modelBuilder.Configurations.Add mechanism) going to be implemented? |
@freerider7777 I don't think EF team has this as a priority in their sights right now. In the meanwhile, may I point you towards the release of https://github.com/Grinderofl/FluentModelBuilder which does what you are looking for and more. |
Ok, Its bin a while since this issue opened. |
@xhevatibraimi not built in, but the description at the top of this page (the first comment) has a small amount of code you can add to your project to enable the same pattern. |
@rowanmiller @xhevatibraimi I have added a project that allows you to configure entities outside of the DbContext.OnModelCreating where you only have to configure where to find the configuration in your Startup class. First you need to create a class which inherits from
Then in your Startup class you just need to tell Entity Framework where to find all of your configuration classes when you are configuring your DbContext.
There is also an option for adding type configurations using a provider. The repo has complete documentation on how to use it. https://github.com/john-t-white/StaticDotNet.EntityFrameworkCore.ModelConfiguration |
@rowanmiller @xhevatibraimi - Hi there, I've developed some code to fill this void and would be interested in contributing it back. The classes I have developed act similarly to the legacy EntityTypeConfiguration in that they allow you to define your mappings in a separate class, cleanly separating the data model from persistence. Similarly to EF6, EntityTypeConfigurations can be added in the OnModelBuilding() method using the ModelBuilder extension method AddConfiguration. While not a 100% match, it's also closer to the syntax of legacy EntityTypeConfiguration than the pattern above. The API directly mirrors the EntityBuilder largely because, under the hood, the classes are merely accumulating the actions to be performed against an EntityBuilder. Since they are a facade over the existing functionality, there's minimal maintenance required and minimal opportunity for things to diverge, but I do recognize that I still need to add some unit tests. If there's any interest, the new code can be viewed in the feature/entitytypeconfiguration branch of my forked repo. An example of the methodology can be seen below (note, in reality this is only a portion of one class).
Each method on the EntityTypeConfiguration is creating an action to be called on the EntityBuilder, which is then invoked when the Apply method is called (by the ModelBuilder.AddConfiguration extension method). Definitely still some work left to do to button things up, but would be happy to do so if it were likely to be used. |
@ajcvickers - Hi there, Is it possible to generate these configuration classes on dbcontext scaffold (Database First) instead of single bulky |
@ilya-chumakov Not currently--see my comment on #8434 |
@mmillican please, can you tell how to add unique key constraint in dot net core fluent api ? |
@djamajo This is not relevant to this issue, but you can call modelBuilder.Entity<Customer>().HasAlternateKey(b => b.Name) to add a unique key constraint on |
Stumbling upon this issue/solution, it worked fine for me, until I have the need to have another generic parameter, like this:
I've added the correspondent interface and class, and changed the The problem is that the type
Any idea on how can i Solve this? |
@DanielSSilva You'll have to specify the concrete type to use for |
@AndriySvyryd thank you for your quick response. That's exactly the solution that I've ended up with. Glad i was on the right way :) |
As a side note, I've also had to change the
because both types are being "catched" by |
@CumpsD @domenkogler You solutions don't work when DbContext is an abstract class and inherited by subclasses wherein the base abstract class is located on a separated library. I'm using Clean Architecture, so models and configurations are in a separate dll. Does anybody here have an idea how to apply configurations from the calling assembly? Core.csproj
--> Configurations
- PersonConfig.cs
--> Models
- IBaseEntity.cs
- Person.cs
- AbstractBaseDbContext.cs
WebApi.csproj
--> SqlServerDbContext.cs // this is the calling assembly, configurations from the base project are not being called during migrations |
whizkidwwe1217 maybe reflection wiil help )) But is not so fast )) like native code ! I guessing many people on ef core Rep Want to make self enterprise systems, that must have user model configuration ! |
Edited by @rowanmiller Oct-13-2016
EntityTypeConfiguration<T>
is a feature in EF6.x that allows you to encapsulate the configuration for an entity type in a class.Here is some code you can use to enable the pattern until we add support in EF Core.
And here is a sample application that uses these types:
The text was updated successfully, but these errors were encountered: