-
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
Allow model building outside of OnModelCreating #11738
Comments
@jagalves When using an empty convention set the model must still be constructed in a valid way--that is, with all required configuration including everything that is normally done by convention. In this case, there is a convention that creates type mappings, so if you don't run it, then you'll need to manually configure the type mapping for every property. In general, it's hard to be sure everything is configured correctly and that the model is valid if you don't let any conventions run. We don't have any documentation on this because it is extremely advanced and not something we recommend people to do. |
Well, this scenario worked fine in 2.0... I have a full complex model over which I have full control on how the mapping is defined and how my domain classes and my database tables are created/related. I'm trying to avoid cases where I generate migrations and then I have to go back and add overrides (like in my example userBuilder->Ignore(x=>x.NotMapped)) to avoid having columns and tables created by accident. This scenario is even worse if you use some other tool to do the migrations, by the way. In other words, I'm trying to use what EF has to offer me, not override what it's trying to guess on my behalf. Is it possible to do that with the example code I provided? |
@jagalves By convention, EF asks the provider for the most appropriate type mapping and annotates the property with that type mapping. If you're not happy with this convention, then you will need to create the type mappings explicitly and annotate them on the model. If you are okay with the type mapper "guessing" the type mapping, then you could ask the type mapper explicitly for each mapping and annotate the model from that...but then you would be doing exactly what the convention does. So I suppose this all depends on the definition of "guess". |
It's not about being "happy". My scenario worked before and now it won't work anymore so I reported it because it could very well be a bug or something the team overlooked. In my particular test case, is there something I can do to make it work? Like adding just that convention manually or removing the ones that would add "NotMapped" or any referenced classes to the model automatically. The type mapping convention seems to be required because explicitly setting the type with HasColumnType still fails. If you believe the ticket is invalid or an unreasonable request you can close it. |
@jagalves The issue is still open because it hasn't been triaged yet. There are no conventions that will add types marked with NotMapped to the model. If you are seeing this, then please file an issue with full details so that we can investigate. Column types are not the same as type mappings. Here is the code that in the convention: foreach (var property in modelBuilder.Metadata.GetEntityTypes().SelectMany(e => e.GetDeclaredProperties()))
{
property.Builder.HasAnnotation(
CoreAnnotationNames.TypeMapping,
_typeMappingSource.FindMapping(property),
ConfigurationSource.Convention);
} This is what you will need to do manually if not using the convention. You can do things with conventions to create a set with just the ones you want, but this requires using internal code since conventions are not public yet, and still requires an advanced understanding of the EF Core model to ensure that you are building a valid model without using certain conventions. |
I called it that to be obvious to whoever reads the code that I don't want it to be mapped if I didn't do it explicitly. If you change the code to keep the default conventions (override OnModelCreating and call GetModel from there with the provided modelbuilder), the test will fail in the assert that checks that it's null. Same thing for properties with a class type: they will throw because I didn't set the primary key. And then I have to go to the mapping add them to a list of the ones I'm ignoring. I had a considerable list before I found out clearing ConventionSets was possible. I'll try tomorrow your suggestion. Too late to think in my timezone. Thanks. |
Notes from triage:
|
I'm hitting this error with something like explained in #4410, so we need a GetCompiled method that uses
And now this project works with 2.0, but gives me this error when I upgrade to 2.1 |
Hi, I have exactly the same issue posted by @sadjadbp when calling the DbContext.SaveChanges Thanks in advance |
Same for me as for @sadjadbp - blocks me from upgrading to 2.1. |
We met the same problem, when tried to create
Then just replace the default ModelSource with created one to create a new |
I tried without luck... honestly i believe problem is somewhere else. |
I'm experiencing the same. Tried in the latest 2.2 as well. Has anyone figured out a fix to this? |
I think I have the same problem when calling DbContext.SaveChanges Microsoft.EntityFrameworkCore.Utilities.Check.NotNull[T](T value, String parameterName) |
same issue. please fix it as soon as possible! |
Having the same issue and this blocks us from upgrading to v2.1. Please fix this soon. |
same issue for me, please fix it asap! |
@sabo3000 @alekrist @Joganoth @mfernandezruiz @AAltemus @luigi68 @almazsr This issue is about the behavior of building the model using an explicitly empty convention set. Can you either:
|
This code runs until version 2.1 and with the 2.1.3 fails
|
About me I think I am not using empty convention set. var connection = System.Data.SqlClient.SqlClientFactory.Instance.CreateConnection(...);
var conventionSet = SqlServerConventionSetBuilder.Build();
var modelBuilder = new ModelBuilder(conventionSet);
modelBuilder.Entity("ADDRESS").HasKey( )... // example...
...
var optionsBuilder = new DbContextOptionsBuilder();
optionsBuilder.UseModel(modelBuilder.Model);
optionsBuilder.UseSqlServer(connection);
...
var dbContext = new DbContext(optionsBuilder.Options)
... Please let me know what i am doing wrong.. |
@mfernandezruiz, @luigi68 You can use a standard way of creating a model by overriding the |
@mfernandezruiz: I need to create model before creating context. And by the way this approach works fine with Entity Framework. |
@luigi68 May I ask why? You can just define your model inside your DbContext. |
We are more or less using the same code as @mfernandezruiz below. No matter if we use empty convention, or conventions built with SqliteConventionSetBuilder or SqlServerConventionSetBuilder, the code fails with the indicated error. We are not using database migrations, in case this makes a difference.
|
@neris : My example is only for reproduce the problem. My application needs to create data models at run time and also needs to handle several data models at the same time, so overwriting 'OnModelCreating' does not help |
Thanks for the additional info; using conventions but outside of OnModelCreating like this looks like a more common scenario than was originally reported. We will discuss what we can do. A couple of random things to note from the discussion:
|
Triage: we will look into adding a |
… the context Fixes #11738 Naming to be discussed. This runs the model-based conventions, but not model validation. Also moved setting or product version annotation to any use of the ModelBuilder and then removed from places in the tests that this would cause problems when the version changes.
@almazsr If you need to rebuild the model based on some external information you can implement |
… the context Fixes #11738 Naming to be discussed. This runs the model-based conventions and model validation. Also moved setting or product version annotation to any use of the ModelBuilder and then removed from places in the tests that this would cause problems when the version changes.
… the context Fixes #11738 Naming to be discussed. This runs the model-based conventions and model validation. Also moved setting or product version annotation to any use of the ModelBuilder and then removed from places in the tests that this would cause problems when the version changes.
… the context Fixes #11738 Naming to be discussed. This runs the model-based conventions and model validation. Also moved setting or product version annotation to any use of the ModelBuilder and then removed from places in the tests that this would cause problems when the version changes.
… the context Fixes #11738 Naming to be discussed. This runs the model-based conventions and model validation. Also moved setting or product version annotation to any use of the ModelBuilder and then removed from places in the tests that this would cause problems when the version changes.
… the context Fixes #11738 Naming to be discussed. This runs the model-based conventions and model validation. Also moved setting or product version annotation to any use of the ModelBuilder and then removed from places in the tests that this would cause problems when the version changes.
… the context Fixes #11738 Naming to be discussed. This runs the model-based conventions and model validation. Also moved setting or product version annotation to any use of the ModelBuilder and then removed from places in the tests that this would cause problems when the version changes.
Note: breaking change for provider tests |
Also broke compat tests. |
@ajcvickers Thanks for supporting our case. Maybe i misunderstood something, but I still get the same error with EFCore 2.2 and the new method FinalizeModel():
leads to this exception when saving changes:
|
@stefan-landgraf-is24 If you use an empty convention set, then you'll still need to make sure that everything that needs to be done in the model actually gets done. This includes setting appropriate attributes for type mappings. The change that was made for 2.2 allows building of a model using conventions to work outside of OnModelCreating. |
@ajcvickers How can I find out what has to be done, if the error message gives no hint at all?
|
@stefan-landgraf-is24 The message could be better, but it's telling you that type mappings do not exist for the properties in the model. See this comment above for details: #11738 (comment) In terms of what has to be done, the easiest by far to get right is to use a model builder with conventions in the normal way. If you really need there to be no conventions, then it's going to be tough to understand and replicate everything that the conventions are doing. I certainly would not attempt it, and I know EF Core pretty well. Some of the potential future work discussed above could make this easier, but it's not high on the priority list right now. |
@stefan-landgraf-is24 You can use |
With EFCore 2, in order to have all mappings explicit, I create the model with an empty ConventionSet.
This scenario causes an exception with EFCore 2.1 (both preview1 and preview2)
Don't know if this is an actual bug or just something that I'm required to add as a convention in order to have a 100% by code mapping. Maybe there's some documentation that I can't find?
Steps to reproduce
Test code attached. Switch between EFCore 2 and 2.1 preview in order to see the different behavior.
TestProject.zip
Further technical details
EF Core version: 2.1 preview 2
Database Provider: Sqlite
Operating system: window 10 1803 17134.1 (and previous)
IDE: at the moment 15.7 preview 4
The text was updated successfully, but these errors were encountered: