Entity Framework Core Cascade Delete Error - asp.net

Though it has been set to on-delete: "ReferentialAction.Restrict" on foreign key "FK_TeamMember_Teams_TeamId", it gives the following error when trying to delete a record from TeamMember table. Can you please help me with how I should get rid of this error?
Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries.
See the inner exception for details.
---> Microsoft.Data.SqlClient.SqlException (0x80131904): The DELETE statement conflicted with the
REFERENCE constraint "FK_TeamMember_Teams_TeamId". The conflict occurred in database "mot", table
"dbo.TeamMember", column 'TeamId'. The statement has been terminated.
Following is the migration code block
migrationBuilder.CreateTable(
name: "TeamMember",
columns: table => new
{
Id = table.Column<Guid>(nullable: false),
MarketingOfficerId = table.Column<Guid>(nullable: false),
TeamId = table.Column<Guid>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_TeamMember", x => x.Id);
table.ForeignKey(
name: "FK_TeamMember_Employees_MarketingOfficerId",
column: x => x.MarketingOfficerId,
principalTable: "Employees",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_TeamMember_Teams_TeamId",
column: x => x.TeamId,
principalTable: "Teams",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
OnModelCreating method I have used the following as well.
modelBuilder.Entity<Team>()
.HasMany(i => i.TeamMembers)
.WithOne(i=>i.Team)
.OnDelete(DeleteBehavior.Restrict);
Thank You

I think the behavior is correct since when the master table deletes a record it should delete its related records in the detail table. No point in keeping it. Data will be redundant. But in case if we want to make such a scenario, though we set CascadeDelete to Restrict within the migration.cs it will not work as expected. The following article will help with understanding the behaviours.
https://learn.microsoft.com/en-us/ef/core/saving/cascade-delete

Related

how insert record on db zf2?

how can try insert a record on data/mydatabase.db a new record.
i'm using zend framework 2 and apiligity for insert a new record on my db
now i can get all records but i can't insert
have this for insert
public function create($data)
{ $sql = new Sql($this->adapter);
$insert = $sql->insert('album');
$newData = array(
'id' => $data->id,
'artist' => $data->artist,
'title' => $data->title
);
$insert->values($newData);
$selectString = $sql->getSqlStringForSqlObject($insert);
$results = $this->adapter->query($selectString, Adapter::QUERY_MODE_EXECUTE);
}
have a error
how insert a new record?
thanks
This is a database error : Integrity constraint violation: UNIQUE constraint failed: album.id.
If you use an ID that haven't been used, your code should work properly.
Basically this means that you successfully asked the database to store your data but he/she politely refused to store it based on his/her configuration.

cakephp 3 deeper associations

I'm trying to find the right way to handel the next tabel setup.
Products is my main table and contains an id.
UsersCarts has an field product_id and with belongsTo it also loads the products.
So far no problem. I also have an table ProductsNettoDeals where I store possible netto prices. This table has it's own id an an product_id for the hasOne relation when loading products in the productcontroller.
When I load the UsersChart it loads it belongsTo products, but I also want the association with the table ProductsNettoDeals, but this table is connected with products through the id (products.id = products_netto_deals.product_id). I cant find the right syntax or association for the querybuilder. What I have so far:
// src/Model/Table/UsersCartsTable.php
namespace App\Model\Table;
use Cake\ORM\Table;
use Cake\ORM\Query;
use Cake\Validation\Validator;
class UsersCartsTable extends Table
{
public function initialize(array $config)
{
$this->addBehavior('Timestamp');
$this->belongsTo('Products');
$this->belongsTo('ProductsNettoDeals');
}
public function validationDefault(Validator $validator)
{
return $validator
->notEmpty('user_id', 'A user id is required')
->notEmpty('product_id', 'A product id is required');
}
public function findCart(Query $query, array $options)
{
$query
->where([
'user_id' => $options['user_id'],
//'active' => '1'
])
->contain(['Products','ProductsNettoDeals'])
//->select(['product_id','created','products.name','products.price','products.delivery_time']);
;
return $query;
}
}
In this setup I always have the problem that the matching of the id's are wrong. With the products it's good. The users_carts.product_id links with the products.id, but the products_netto_deals.product_id should link with product.id and not with the users_carts.id. I tryed foreign key and bind, but both are an part of an solution.
Beside this problem, when connecting the association ProductsNettoDeals I get an error when activating the commented active => '1'. This field indicates if an record is active and should be loaded. The same field exist in the products_netto_deals tabel to indicate if an netto price is active.
Error: SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'active' in where clause is ambiguous
Can anyone point me in the right direction for the correct way of the association and the error warning. Thanks in forward.
CakePHP uses joins for fetching associations, in order to speed ud the information retrieval process. This means that when having column names repeated across different table, you will need to prefix the column names in the query clause"
Instead of:
$query->where(['active' => true]);
Do:
$query->where(['UsersCarts.active' => true])

Asp.Net Identity 2 duplicate username check

UserManager in Asp.Net Identity 2 prevents creation user with duplicate username through additional request to database to find possible duplicate. I think this is error prone and can cause concurrency errors. The correct mechanism should rely on on unique constraints or indexes. Am I wrong and do I miss something?
Links to source:
CreateAsync and ValidateUserName
No, you are not wrong. And Identity adds the unique index on Username column:
And the migration code for this table is:
CreateTable(
"dbo.AspNetUsers",
c => new
{
Id = c.String(nullable: false, maxLength: 128),
/* .... SNIP .... */
UserName = c.String(nullable: false, maxLength: 256),
})
.PrimaryKey(t => t.Id)
.Index(t => t.UserName, unique: true, name: "UserNameIndex");
Unique index is clearly set on the column.
p.s. you are looking on Identity v3 - it is not released. Current Identity v2.1 is not open source yet.

Update an Entity with Unique Key - Insert instead of update

I have this method in my service:
public function updateCountry($p_entity) {
var_dump($p_entity->getId()); //return 3 (as expected)
var_dump(get_class($p_entity) ); //return Country (as expected)
$this->em->persist($p_entity);
$this->em->flush();
}
I call it by
$country = $em->getRepository('blabla')->find(3);
$my_service->updateCountry($country);
But the request generated is
Doctrine\DBAL\DBALException: An exception occurred while executing
'INSERT INTO country (code, label , created_at, updated_at)
VALUES (?, ?, ?, ?)' with params ["EN", "England", "201
3-08-23 00:00:00", null]:
I have a unique doctrine constraint
this is my country.orm.yml
To\Bundle\Entity\Country:
type: entity
table: country
repositoryClass: To\Bundle\Entity\CountryRepository
fields:
id:
type: integer
id: true
generator:
strategy: AUTO
code:
type: string
length: 255
unique: true
nullable: false
Why have I an insert request generated instead of the update one?
Can you persist new entity at all?
If you can, try merging your object instead:
public function updateCountry($p_entity) {
var_dump($p_entity->getId()); //return 3 (as expected)
var_dump(get_class($p_entity) ); //return Country (as expected)
$this->em->merge($p_entity); // MERGE not PERSIST
$this->em->flush();
}
From official docs:
If X is a new entity instance, a new managed copy X’ will be created
and the state of X is copied onto this managed instance.
So, basically, EntityManager::merge can be used to both persist newly created object and merge exsistent one...
You shouldn't persist existing in DB entity, only new one.
So if you get entity from DB and want to update it
you should
$entity->setName()
$em->flush

Query builder join on one to many relationship

I have a LastTrait object that has a many to one relationship with my user object: one user can have many different lastTrait:
YOP\YourOwnPoetBundle\Entity\LastTrait:
type: entity
table: null
fields:
id:
type: integer
id: true
generator:
strategy: AUTO
traitCategoryID:
type: integer
verseID:
type: integer
manyToOne:
user:
targetEntity: User
inversedBy: lastTrait
joinColumn:
name: user_id
referencedColumnName: id
I need to retrieve the verseID knowing the userID and traitCategoryID. So I created a Repository for my LastTrait object:
<?php
namespace YOP\YourOwnPoetBundle\Repository;
use Doctrine\ORM\EntityRepository;
class LastTraitRepository extends EntityRepository {
public function findOneByTraitCategoryID($userID, $traitCategoryID)
{
return $this->getEntityManager()
->createQuery('SELECT l
FROM YOPYourOwnPoetBundle:LastTrait l
JOIN l.user u
WHERE l.traitCategoryID = :categoryID AND u.id = :userID')
->setParameters(array(
'categoryID' => $traitCategoryID,
'userID' => $userID,
))
->getResult();
}
}
?>
However, when I call :
$lastTrait = $this->getDoctrine()
->getRepository('YOPYourOwnPoetBundle:LastTrait')
->findOneByTraitCategoryID($user->getID(), $collector->getTraitCategory()->getID());
I always get NULL, even though I should get a LastTrait object back!
What am I doing wrong here?
I think you should be thinking more in entities and less in foreign keys.
Try this in your method.
public function findOneByTraitCategoryID($userID, $traitCategoryID)
{
return $this->findOneBy(
array(
'traitcategoryID' => $traitCategoryID,
'user' => $userID
));
}
You can call ->getVerse()->getId(); after this or return the id directly on the method (too narrow for future uses IMO).
This only works if a user only has one trait per category, otherwise you don't have enough data to get a specific trait.
The issue was that I forgot to register the repository in my entity:
YOP\YourOwnPoetBundle\Entity\LastTrait:
repositoryClass: YOP\YourOwnPoetBundle\Repository\LastTraitRepository
type: entity
table: null
fields:
id:
type: integer
id: true
generator:
strategy: AUTO
traitCategoryID:
type: integer
verseID:
type: integer
manyToOne:
user:
targetEntity: User
inversedBy: lastTrait
joinColumn:
name: user_id
referencedColumnName: id
After adding the repositoryClass line, my custom Repository class is called and I get the desired result.
However, #dhunter's answer made me realize that I didn't even need a custom Repository class. I can get the desired by simply using the regular findOneBy function from my controller:
$lastTrait = $this->getDoctrine()
->getRepository('YOPYourOwnPoetBundle:LastTrait')
->findOneBy(
array('user' => $user->getId(), 'traitCategoryID' => $collector->getTraitCategory()->getID())
);
Hard to tell. Try echoing either DQL or SQL before retreiving results:
$q = $this->getEntityManager()->createQuery(....);
die($q->getSql()); //or getDql();
If, for some reason, you have invalid mapping (which I don't see above) you should see it here.
Also, try wrapping method with try-catch with most general Exception catch and seeing if it catches anything...
Furthermore, what is bugging me is the fact that you get NULL back...

Resources