I need to use an 'DropCreateDatabaseIfModelChanges' - Initializer class, because I want to create one special entity (table), if it doesn't exist. My problem is, that I've also got another entity in my DbContext, which shouldn't be part of the model compatibility check.
I'm getting the following error message:
Model compatibility cannot be checked because the EdmMetadata type was not inclu
ded in the model. Ensure that IncludeMetadataConvention has been added to the Db
ModelBuilder conventions.
Is there any possibility to exclude a special entity from this check?
EDIT:
I've done what Devart has suggested. The problem seems to be different, than I first tought. It all works fine, if I let EF create a new database with my CheckedContext. But I'm getting the error message above, when I'll try to use my NonCheckedContext wich should use an existing table ...
EDIT2:
This is a working solution. Everything works fine, when the database doesn't exist before. But it's no option for me, to Drop/Create the database.
A possible solution: create a context class inherited from DbContext, and then create two separate subcontexts inherited from the base one - CheckedContext and NonCheckedContext, and set the Database Initialization Strategy accordingly.
Please note that you should access the CheckedContext first so that it fires all its checks.
Related
I am use EF6, the database-first, i.e. with the creation of an EDMX model. One table is used by previous developers to store different entities. It's very wrong and it causes trouble.
The task is to leave the existing code as is and try to create different classes from this table. It seems to me the most logical to create several Views based on this table, each of which would represent the required class. You can write insert, update, delete to such View, since it refers to one table. The problem is that when you try to update an object created from the View, an error occurs.
System.Data.Entity.Infrastructure.DbUpdateException: "Unable to update the EntitySet 'Sample' because it has a DefiningQuery and no element exists in the element to support the current operation."
The entity understands that this is a view and, in general, cannot be updated.
So far, I see 2 ways to solve the problem:
Create Update, Insert, Delete function manually.
Manually configure the View data through the Fluent API (if possible).
I like the second option better. The problem is that the Fluent Api is more of a code-first approach. I can't get the OnModelCreating (DbModelBuilder modelBuilder) method to be called.
Is it possible to use EDMX model and Fluent Api together?
What other solutions can you suggest?
The goal
My goal is to create a hierarchy of DbContexts each one residing in different assembly. Whatever references are required are established correctly so that the C# code compiles successfully.
The scenario
Let's say I create a db context, e.g. DbChild, inheriting from a base one, say DbBase.
The base context has some entities defined in OnModelCreating(). A migration for these entities is created and successfully applied to the database, thus the db schema contains the DbBase model mapped.
Needless to say DbChild uses the very same connection string and therefore the same database (I tried a number of ways to supply the connection string, the last one specifying it directly in optionsBuilder.UseSqlServer("<conection string>");).
Actual result
Creating a migration for the child context, however, includes the base model as part of the child one, which results in duplicate SQL objects in the DB.
Required result
A "clean" migration including only SQL objects (EF entities) from the child context is required.
Any ideas how to achieve this?
Thanks in advance.
PS: calling Ignore(...) in OnModelCreating() might be a workaround but it needs everything referenced in DbBase to be referenced in DbChild which is not an option.
PS2: Totally ignoring the base model while create the child one is not an option too - child uses an entity from base as a relationship.
EDIT: The snapshot <ContextName>ModelSnapshot.cs contains a "copy" of the model which gets updated with each migration. This is where every migration starts up. In complex models, however, it would be much easier, and what is much more important - safe, to have the snapshot file generated programmatically out of the existing database instead of copying, changing namespaces, renaming so as to have the context name reflected etc.
So, the questions may be transformed to "How to generate database snapshot when applying the first migration?".
Any ideas are welcome.
When creating a new derived context, after setting up the DB connection string but before adding any derived types to the context, you should create a migration that saves the snapshot of the pre-existing base context types.
In EF6, this would be done by creating a migration with Add-Migration PreExisting –IgnoreChanges. This produces a migration, where the internal model contains an updated snapshot, but the Up and Down methods of the migration are empty.
I'm not up to date on whether EF Core does support the -IgnoreChanges switch currently. According to What is the equivalent of the -IgnoreChanges switch for entity-framework core in CLI?, an alternative is, to manually clear the Up/Down methods after creating a migration.
Only after the first snapshot migration is created, start with adding additional entities to the derived context and creating migrations to add them to the database etc.
For some reasons we need to update Views inside the Entity Framework.
So we followed this solution on another question and it worked like a charm!
BUT here is the problem:
if we update our model (for some new fields or tables/views) the complete Mappings are destroyed and after updating we get the Warning
Error 11007: Entity type 'UpdateView1' is not mapped.
After this it's not even possible to load the entities because all Mappings are lost.
So how to design the views to be able to post updates using the Views AND to be able to update the edmx file?
MS is dropping support for EDMX files going forward in Entity Framework - in part due to the difficulty of keeping the database, EDMX, and POCOs all sync'd, as you are experiencing. (Anyone can edit any of the 3, then changes are lost when a sync is done).
So they recommend using the Code First approach. Code First is a bit of a misnomer and causes some confusion.
Code First doesn't mean you have to start with code.
You can start with the database and then write your POCOs to match it (as in your case). Doing so allows you to preserve all your mappings and such because you just adjust your code to match the structure already present in your database.
Another misconception is that you have to use migrations. You do not. You are welcome to not enable migrations and manually edit both the database schema and POCOs as long as you ensure they remain in sync.
Is it possible to tell Entity Framework to ignore any custom tables I add to the database. For example, say if I use the sqlmemberhipprovider in the same database as the one used for EF, can I tell EF to just ignore whatever tables I haven't already created classes for? Right now, it's giving the error
"The model backing the 'xxx' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269). "
I don't want EF to do anything on the extra tables it doesn't recognize.
I figured out what I was doing wrong. It wasn't the Membership tables that were causing the problem it was another table I deleted manually that EF was tracking.
Have you tried setting your initializer to null?
This question already has answers here:
Entity Framework: Ignore Columns
(7 answers)
Closed 9 years ago.
I have auto generated model from a database in Entity Framework version 4.1.10331.0.
I want to ignore a column from an entity without using the Fluent Api and without changing the ObjectContext into DbContext (and of course without deleting the column from the SQL table) and without marking the property generated in the model with the attribute NotMapped, because whenever I update my context in the model that column will reappear.
Can someone please help me in this case?
Thanks and best regards Ben
I don't see the problem updating your EF each time you regenerate the model, but I can propose 2 solutions:
Create a View that contains the columns you need, then generated it in EF.
Create another class derived from you entity that will show the data you want. This class will be your "application Entity" (As you know additional management should be considered here)
EF database-first is very under-tooled in many places. Similarily to your problem, if you generate a model from DB and rename a column in CodeSpace (so column users.col_chr_UsrName is just User.Name), you also would lose it when regenerating the model.
If I remember well, in EF3, EF4 and even in EF5 there is no way to preserve them. If you just "update" the model, they have a chance of surviving, but regenerating never preserves anything.
You can try to create a script or set of scripts that you will run after regenerating, and those scripts may seek and apply fixes to the generated model. But thats, well, "workaround" (literally, work and around), not a real solution.
Another thing, with more work, is to define Views or StoredProcedures (or custom table mappings) that will handle the projection, but they sometimes also may get hairy after regenerating (especially custom table maping which will always evaporate).
You can actually ignore the unwanted columns and prepare a set of light LINQ wrappers/accessors that will perform the projection, and put them in some static MyTables class and use that class instead of RawTable. That will work and may be usable, but is not again pretty.
IMHO, the best approach is to use either a script that will fix the model afterwards, or live with the unwanted columns, or .. not use the autogeneration from within the designer. Try to find another, more smart, generator.