EF Core 7.0 Migration Ignores DeleteBehavior.NoAction - entity-framework-migrations

I have an EF Core model with a root entity type that has multiple one-to-many relationships with other entity types. Some of these child types also relate to each other, so I understand that I need to take precautions to avoid circular reference issues when deleting a root entity instance.
Without any explicit model builder configuration between the root entity type and its child types, the resulting migration includes clauses like this:
migrationBuilder.AddForeignKey(
name: "FK_Merchants_Platforms_PlatformId",
table: "Merchants",
column: "PlatformId",
principalTable: "Platforms",
principalColumn: "Id");
If I attempt to run this migration, I see the following error:
In an attempt to solve this problem, I added explicit model builder configurations, which force NoAction on delete. Here's one example, applied to the child entity type:
builder
.HasOne(e => e.Platform)
.WithMany()
.HasForeignKey(e => e.PlatformId)
.OnDelete(DeleteBehavior.NoAction);
The above explicit change has no effect on the generated migration. However, if I change the DeleteBehavior to something other than NoAction, it produces the desired effect:
builder
.HasOne(e => e.Platform)
.WithMany()
.HasForeignKey(e => e.PlatformId)
.OnDelete(DeleteBehavior.Restrict);
migrationBuilder.AddForeignKey(
name: "FK_Merchants_Platforms_PlatformId",
table: "Merchants",
column: "PlatformId",
principalTable: "Platforms",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
Based on what I am seeing above, I guess NoAction is the default configuration and is implicitly applied when a migration is executed. However, if that's the case, it is not clear why I am seeing runtime migration errors.
Can anyone suggest the correct model builder configuration to force NoAction in the generated migration?

Related

Cascade deleting one-to-one linked entities in EntityDAC

Using Delphi XE5 and Devart EntityDAC ORM.
I have two entities linked one-to-one:
Project( Id, Name, ... ) and ProjectSchedule ( Id, ProjectId, ... );
In general schedule's fields may be easily inluded in Project table but I separated it for further possible needs. So, in Entity Developer I linked them as one-to-one relationship with Cascade=True and Delete_Rule=Cascade. Ok.
But when I try
project.DeleteAndSave( True );
I get and DB exception: FK violated. Child record found.
But if I change relationship to one-to-many the same works fine. But in this case access to schedule looks like
project.ProjectShedules.First
which is really terrible.
How to cascade delete an one-to-one related entities?

How to create model from database preserving 'default' constraint values

My existing table contains nearly 50 columns, most of them have the 'default' constraint.
I have created the model based on this database table. All seemed ok, until i tried to insert a new row. I've got a sql server error stating that some column cannot be null. It appears that creating a model from the database did not preserve the default constraints.
I edited the model manually adding all the defaults and after that inserting didn't fail.
So my question is, how do i create a model that automatically picks up default constraints associated to the columns?
Using mvc4, visual studio 2010, sql server 2008 r2.
Google search didnt make sense as all the people seemed to be talking about something different than what i need.
Pretty sure my answer from Possible to default DateTime field to GETDATE() with Entity Framework Migrations? will work for you too. By using a modified MigrationCodeGenerator class and iterating through the operations list you can update the columns and add DefaultValueSql values based on whatever rules you need.
Well, you have a number of options. You could set the default values in the Model's default constructor. I think this is the better solution.
If you must have the default constraints in your database you could do set defaultValueSql in your data migrations like this:
AddColumn("ExistingTable", "NewColumn",c => c.Int(nullable: false, defaultValueSql: "0"));

EF 4.1 CodeFirst GetValidationErrors

If I have defined next in map file (1-to-Many relationship between Units and Machines):
this.HasRequired(t => t.Unit)
.WithMany(t => t.Machines)
.HasForeignKey(d => d.UnitId);
When I add new entity, Machine.UnitOfMeasurement = null, sp why does DbContext return no validation problem when calling GetValidationErrors and what can I do to detect them. If I allow EF to try to update, it will return meaningless message to user, like foreign key reference error, while I can extract meaningful information to user from DbEntityValidationResult (ex property name that issued a validation error).
I am using IDataErrorInfo for validation rules, not Attributes.
EF validation does not validate navigation properties. The reason for this is that a navigation property may be null not because a related entity does not exist but because lazy loading is enabled and the related entity is just not loaded. Also, even if the navigation property is null you might have set the corresponding foreign key property which basically means that relation exists but the navigation property has not been updated yet. Also note that forcing loading related entities would mean that validation brings your entire database to memory (after loading related entities they will be validated what would result in loading related entities of newly loaded entities and so on) - you don't want this to happen (EF actually turns off lazy loading during validation to prevent from this).
EF Validation does not support IDataErrorInfo - only validation attributes and IValidatableObject.

How to map a model to a database view using Datamapper

This sounds very simple however I cant seem to find a answer, how do you map a view to a model in datamapper? If I remove the ID field which my view doesnt have, datamapper complains, if I leave it there then everytime I execute a select it says my column id doesnt exist, because it's a view not a table.
DataMapper 1.x does not have native support for views. It expects models to have at least one property that acts as the primary key.
This primary key will normally be used for specifying updates and lazy attribute loads.
When your view does have a column with unique values just specify :key => true in the property options that belong to this column.
No need to specify a property with the name :id.
When you do not have a column with unique value, use a compound primary key (CPK). A set of columns that form a unique combination of values:
class ModelFromView
include DataMapper::Resource
property :key_like_property_a, String, :key => true
property :key_like_property_b, Integer, :key => true
property :other_property, Integer
...
end

Symfony - Add a column to a table without losing already generated classes

How can I add a column to a Database table without overwriting the classes already generated? (Doctrine) What files do I have to edit?
If I simply add the column in the database, I can't use the set and get functions of Doctrine ORM.
Use doctrine migrations. It allows you to modify your schema, update the database and your model without also losing the existing data in your database (in case it is relevant).
http://www.symfony-project.org/doctrine/1_2/en/07-Migrations
Applicable for symfony 1.4 too
You should never edit the base classes (BaseFoo.class.php) as these get overwritten everytime you generate the models from the schema. The other files are never overwritten so it's safe to edit.
Doctrine 1.2:
Go to models folder, open generated class that reflects table to which you have added a column. Add
$this->hasColumn('id', 'integer', 8, array(
'type' => 'integer',
'autoincrement' => true,
'primary' => true,
'length' => '8',
));
to setTableDefinition method.
Note, that your changes will be overwritten on generate-models, so make sure you populate it to YAML/DB schema
See Doctrine Models Definition Manual for reference.
Doctrine 2
Samples given for Annotations Driver, see Doctrine2 manual for other XML and YAML drivers
Just add new property to your #Entity class with #Column annotation on it:
/** #Column(type="integer", name="new_column") */
protected $new_column;

Resources