DbContext with Database changes - database

I'm now using Entity Framework 4.3 DbContext to generate database entities, my question is when i change the database, how can i ensure the auto-generated code are updated? where does EF to store database rules, like allow null from No to Yes. When i use the Update Model From Database function from .EDMX file, it seems does not update the allow null rules of the table. How can i solve the database changes problem. Where is the code behind to store all these rules.
The error message:
Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
But when i delete all EF auto-generated file and re-generate it again, it seems the rules are updated. But i thought it is not a good way to solve the problem during development period.

When i use the Update Model From Database function from .EDMX file, it
seems does not update the allow null rules of the table.
That is correct behavior. EDMX file has three parts:
database definition (only visible in model browser)
class definition (that is what you see in designer)
mapping between definitions (that is what you see in mapping details)
When you use Update from database the designer will completely replace database definition and adds new tables or columns to mapping and class definitions. It will never try to remove or change anything. The reason for this is that class definition is customizable. If you make your changes you don't want designer to touch them. Update from database has only actual state - it doesn't know which changes were made by you and which changes are caused by modifying the database so it simply use the better way - don't modify anything and let you to correct inconsistencies.

Related

How to update models in asp.net through database first approach while keeping some previous methods alive

I have the following columns in the Patients table:
I've created models using the following command.
Scaffold-DbContext "Server=.;Database=Tasks3;Trusted_Connection=True;"
Microsoft.EntityFrameworkCore.SqlServer
-OutputDir Models\MainModel
Screenshot of Patient Model
I've some methods in context class to make my connection string dynamic. Actually I used to fetch data from tokens and after some logic connection string changes from client to client.
Now the problem is here, when I make changes in patients table (for instance, I changed CNIC column from CNIC5 to CNIC) and run the following command with -Force keyword, it delete all the data from the previous Tasks3Context class (DbContext).
Scaffold-DbContext "Server=.;Database=Tasks3;Trusted_Connection=True;"
Microsoft.EntityFrameworkCore.SqlServer
-OutputDir Models\MainModel -t <Patient> -f
Tell me some method that update models and make changes in only specific model and column.
Thanks in advance!
I tried the database update procedure, and when I used -Force for the second time, there was a problem similar to yours. The specific reasons are as follows:
The code generated by EF Core is your code. Feel free to change it. It will only be regenerated if you reverse engineer the same model again. The scaffolded code represents one model that can be used to access the database, but it's certainly not the only model that can be used.
Customize the entity type classes and DbContext class to fit your needs. For example, you may choose to rename types and properties, introduce inheritance hierarchies, or split a table into multiple entities. You can also remove non-unique indexes, unused sequences and navigation properties, optional scalar properties, and constraint names from the model.
You can also add additional constructors, methods, properties, etc. using another partial class in a separate file. This approach works even when you intend to reverse engineer the model again.
After making changes to the database, you may need to update your EF Core model to reflect those changes. If the database changes are simple, it may be easiest just to manually make the changes to your EF Core model. For example, renaming a table or column, removing a column, or updating a column's type are trivial changes to make in code.
More significant changes, however, are not as easy to make manually. One common workflow is to reverse engineer the model from the database again using -Force (PMC) or --force (CLI) to overwrite the existing model with an updated one.
Another commonly requested feature is the ability to update the model from the database while preserving customization like renames, type hierarchies, etc. Use issue this to track the progress of this feature.
Warning
If you reverse engineer the model from the database again, any changes
you've made to the files will be lost.

Entity Framework Core not updating models after a SQL Server trigger updates and a new query of the database

I have an issue with a model not updating to the latest version after requiring the database (probably due to change tracking?).
I add the model to the dbset and save it through the context. At this point there is a server side trigger that updates a field with a link to another table pk column.
After adding the record i need to know the value in the updated column. I requery the database, and a SQL Server trace shows that the new value is returned, but the model value is not updated.
I have tried dethatching the entities similar to this answer. but this does not work.
I have worked around it by creating a new scope from the service scope factory and creating a second instance of my context, but would like to know why this happens and how to avoid it (I have no control of the database so I can't remove the trigger and do everything in code sadly).
Thanks
Paul
Ivans answer in the comments takes care of this. anotating the property in the model with [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
takes care of everything atuomatically.
Thanks for the help

reinitialize code first created tables, but leave existed tables data on place with entity framework 6

Let's say I have 10 entites. 8 of them completelly new and build with EF Code-first aproach. So before I was using DropCreateDatabaseIfModelChanges initialization strategy and that's worked perfect for me.
But now I have 2 entites which build from database based on some 3rd party data, and I need this data all the time, I can't allow EF to drop this tables even if model chnages. I need something more inteligent there.
Which is correct approach in that case?
In short, I want something quite similar. I just need DbInitializer behavior, but per table basis, instead of per Database. I wan't Code-first entities work the same as before, regerating and all that stuff. But add only something custom for this specific 2 DB based entities.
You could use EF Code First Migrations
First, you need to run the Enable-Migrations command in Package Manager Console. This command will add a Migrations folder to our project. This new folder contains the Configuration class that allows you to configure how Migrations behaves for your context.
Now, after that,If you followed the required steps, you can run "update database" from the "Package Manager Console" and add the eight new tables to your DB:
Example:
Make the changes in your model (add the eight new entities)
From the Package Manager Console: Run Add-Migration [Migration Name]
Make any neccessary changes to the generated code (this is optional).
From the Package Manager Console: Run Update-Database
If you don't change or remove any property related to your existing entities, you should not loose the data that you already have in DB.
Update
To achieve what you want you can use Automated Migration. This way when you run your application, you will always get your database in the latest version because EF will do implicit migration every time it is needed - in the purest version you never need to do anything more than enabling automatic migrations.
First, you need to set the database initializer in the context class with the new db initialization strategy MigrateDatabaseToLatestVersion as shown below:
public class YourContext: DbContext
{
public YourContext(): base("DefaultConnectionString")
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<YourContext, YourProject.Migrations.Configuration>("DefaultConnectionString"));
}
}
Later, in the constructor of the Configuration class you have to enable automatic migrations:
public Configuration()
{
AutomaticMigrationsEnabled = true;
}
Now, if you are working with an existing database, before add your new eight entities, you need to do this first:
Run the Add-Migration InitialCreate –IgnoreChanges command in
Package Manager Console. This creates an empty migration with the
current model as a snapshot.
Run the Update-Database command in Package Manager Console. This
will apply the InitialCreate migration to the database. Since the
actual migration doesn’t contain any changes, it will simply add a
row to the __MigrationsHistory table indicating that this migration
has already been applied.
After that, you can apply the changes that you want to your model (adding, for example, the new eight entities), and when you execute your app again, EF will do the migrations for you.
In case that you are going to change
someting that provoke some inconsistency regarding to your database
schema that it could end in data loss, an exception will be throw.
If this exception is not thrown, you don't have to worry about loss
your data, it will remain intact in your DB.
As an aditional information, if you don't mind loose your data (which I think this is not your escenerario, but is useful to know anyway) you can set in true the AutomaticMigrationDataLossAllowed property (its default value is false), and no exception will be thrown in case you are going to loose some data in your DB in the execution of a migration.
public Configuration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed=true;
}

Cakephp automated validation generation from MySQL database constraints

I'm looking for an easy solution to generate automatically the validation rules in the model from the database constraints in Cakephp because I don't want to make that all by hand with cake bake. So e.g. if there is a NOT NULL constraint for a field in the database it should create a "not empty" validation rule for the field.
So is there a tool that can do this sort of thing?
CakePHP does not support this by default, but I like the idea.
But you could implement that by overloading AppModel::__construct(), adding code into the AppModel::beforeValidate() callback, load the schema by using CakeSchema for the table the model is using and loop over the schema it returns and build rules on the fly and set them to $this->validate.
If you don't want a specific model do it you could add another property like boolean autoValidationRules. Also check if notEmpty is not already set and don't overwrite it automatically or merge it, depends on your needs.
Edit: Try this behavior, I just hacked it together because I like the idea. Going to add an unit test later tonight.
https://github.com/burzum/BzUtils/blob/develop/Model/Behavior/AutoValidateBehavior.php
Indeed there is no built-in feature in CakePHP for this.
Otherwise if you don't want to use the console, you can use an online tool that allows you to design your applications : Models, relations and validations rules, and then automatically generate a SQL file with the right constraints on columns, your Models with the corresponding validation rules for fields, Controllers and Views : Online Cake Bake.
You do not get to do exactly what you want, but at least you get to design your database's constraints and your validation rules at the same time which saves a lot of time.

Using liquibase, how to handle an object model that is a subset of database table

Some days I love my dba's, and then there is today...
In a Grails app, we use the database-migration plugin (based on Liquibase) to handle migrations etc.
All works lovely.
I have been informed that there is a set of db administrative meta data that we must support on every table. This information has zero use to the app.
Now, I can easily update my models to accommodate this. But that answer is ugly.
The problem is now at each migration, Liquibase/database-migration plugin, complains about the schema and the model being out of sync.
Is there anyway to tell Liquibase (or GORM) that columns x,y,z are to be ignored?
What I am trying to avoid is changesets like this:
changeSet(author: "cwright (generated)", id: "1333733941347-5") {
dropColumn(columnName: "BUILD_MONTH", tableName: "ASSIGNMENT") }
Which tries to bring the schema back in line with the model. Being able to annotate those columns as not applying to the model would be a good thing.
Sadly, you're probably better off defining your own mapping block and taking control of the Data Mapper (what Hibernate essentially is) yourself at this point. If you need to take control of the way the database-integration plugin handles migrations, you might wanna look at the source or raise an issue on the JIRA. Naively, mapping your columns explicitly in the domain model should allow you to bypass unnecessary columns from the DB.

Resources