update database : error asp.net core with mysql - mysql

im using mysql database with EF core .
i use Identity Schema to my existed MySql database , after doing a migration , update database generate this :
"A schema "Identity" has been set for an object of type "CreateTableOperation" with the name of "Role". MySQL does not support the EF Core concept of schemas. Any schema property of any "MigrationOperation" must be null. This behavior can be changed by setting the SchemaBehavior option in the UseMySql call."
error pic
So how to set the schemabehavior option .
With gratitude.

Update your service registrator (Startup.cs) and modify the DB context to set the SchemaBehavior option as one of the following:
// Throw an exception, if a schema is being used. This is the default.
options.UseMySql(myConnectionString, b => b.SchemaBehavior(MySqlSchemaBehavior.Throw))
// Silently ignore any schema definitions.
options.UseMySql(myConnectionString, b => b.SchemaBehavior(MySqlSchemaBehavior.Ignore))
// Use the specified translator delegate to translate from an input schema and object name to
// an output object name whenever a schema is being used.
options.UseMySql(myConnectionString, b => b.SchemaBehavior(MySqlSchemaBehavior.Translate,
(schema, entity) => $"{schema ?? "dbo"}_{entity}"))

// Just ignore all schemas:
optionsBuilder
.UseMySql(
connectionString,
serverVersion,
o => o.SchemaBehavior(MySqlSchemaBehavior.Ignore))
// Translate schemas into a table name prefix like `schema_table`:
optionsBuilder
.UseMySql(
connectionString,
serverVersion,
o => o.SchemaBehavior(MySqlSchemaBehavior.Translate, (schema, table) => $"
{schema}_{table}"))

Related

Laravel Eloquent supporting MariaDb dynamic column

For Dynamic column supported in Maria-DB and in MySQL we have JSON column type. For one of our projects, we should be implementing a database for Maria-DB (not Mysql).
The Dynamic Column is supported using yii2-dynamic-ar package.
how can can override Eloquent orm in Laravel to add dynamic-columns. in the Yii package which added this feature to ActiveRecord this classes can override ActiveRecord class
implementations classes in Yii framework to support in ActiveRecord ORM:
DynamicActiveRecord.php
DynamicActiveQuery.php
I just created package for handling MariaDB dynamic Column using eloquent and query builder.
To install package run this command:
composer require halalsoft/laravel-dynamic-column
You can start using the package by adding the HasDynamicColumn trait and use Dynamic as attribute cast to your models.
An example:
use Illuminate\Database\Eloquent\Model;
use Halalsoft\LaravelDynamicColumn\Dynamic;
use Halalsoft\LaravelDynamicColumn\HasDynamicColumn;
class MyModel extends Model
{
use HasDynamicColumn;
protected $casts
= [
'the_column' => Dynamic::class,
];
}
Now You can use dynamic column like json column using eloquent or query builder:
$modelData = MyModel::find(1);
$columnData = $modelData->the_column;
$columnData['data1'] = 'value';
$columnData['data2'] = 'value2';
$modelData->the_column = $columnData;
$modelData->save();
You can also create data field as array
$newData = MyModel::create([
'other_column' => 'this just another column data',
'the_column' => ['data1'=>'value1','data2'=>'value2']
]);
to update a json field/key you use, you may use the -> operator when calling the update method:
$page->update(['content->data1' => 'value1new']);
or you can still update whole column using normal array:
$page->update(['content' => ['data1'=>'value1new','data2'=>'value2new']]);
You can set as array using other method like updateOrCreate(), firstOrCreate(), etc.
This package also support query builder using:
Model::query()->where('the_column->data1', 'value1')->first();
This package is still new, if any issue or request just go to github issue
You can have a cast defined for the column in the Model class
//Model class
protected $casts = ['my_column' => 'array];
You can define the datatype for the column as text if you want or json, with the cast defined, you will be able to work with the column data as associative array.
There's also a package to add json datatype in migration for mariadb - it may be of help
https://github.com/ybr-nx/laravel-mariadb

Select default schema for MS SQL

I need to configure Yii2 to work with Microsoft SQL server.
The db configuration file (db.php) is something like this
return [
'class' => 'yii\db\Connection',
'dsn' => 'sqlsrv:Server=192.168.77.111;Database=xyz',
'username' => 'xy',
'password' => 'xyz',
This works only if i add before the table name in the tableName() function inside all models the correct schema name.
For example:
public static function tableName()
{
return '{{%xyzschema.users}}';
}
How can i set the db configuration so xyzschema is always added when connecting to the table?
I tried with tablePrefix and schemaMap with defaultSchema but it doesn't work
The error returned is
Invalid object name 'users'.
or
Invalid object name 'xyzschema.users'.
If i add tablePrefix to db.php
Update: The defaultSchema property inside connection's schemaMap/Schema config array gets ingored
For this case i solved changing the schema to the standard "dbo" for each table.

CakePHP 3.x UnitTest "Base table or view not found"

I get an Error-Message in a UnitTest in CakePHP 3.2 and the official documentation doesn't help me here anymore. I think the error has something todo with the SQL-Joins I try to use.
The Error-Message is the following:
`1) App\Test\TestCase\Controller\GetContentControllerTest::testIndex
PDOException: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'contentmapper_test.CmDeviceclasses' doesn't exist`
In my Testclass GetContentControllerTest I load my fixtures that I need and that creates my Database-Tables on start:
`public $fixtures = [
'app.cm_content_options',
'app.cm_content_addresses',
'app.cm_deviceclasses',
'app.cm_properties'
];`
In the setUp()-Method I load the Main-Table:
`public function setUp()
{
parent::setUp();
$this->CmContentOptions = TableRegistry::get('CmContentOptions');
}`
My Test-Method testIndex() looks like this:
public function testIndex()
{
//find the belonging ContentOption to address data
//submitted by the client
$this->testFindAllByUriAndDeviceclassAndBoxId();
assert($this->arrObjContentOptions->count() == 1);
}
The testFindAllByUriAandDeviceclassAndBoxID() looks like shown in the following Image (the Editor is not able to prettyprint it correctly):
testFindAllByUriAandDeviceclassAndBoxID()
It's hard to describe the whole Context; I hope it is possible to understand.
The Error happens exactly on the statement shown in the image:
$result = $query->toArray()
I think I just forgot something to add in the setUp() Method or something like that.
I hope anyone can help.
You joins are set up incorrectly, you're mixing up aliases and table names.
The alias is the key of the join array, and the table key should hold the actual database table name, not the table class name.
Given that you are following CakePHPs naming conventions for your database table names, your join setup should look more like this
[
'CmDeviceclasses' => [ /* < this is the SQL alias */
'table' => 'cm_deviceclasses', /* < this is the database table name */
'type' => 'LEFT',
'conditions' => [
'CmDeviceclasses.classname' => $this->deviceclass
]
],
'CmContentAddresses' => [
'table' => 'cm_content_addresses',
'type' => 'INNER',
'conditions' => [
'CmContentAddresses.uri' => $this->uri,
'CmContentAddresses.boxid' => $this->boxid,
]
],
],
[
'CmDeviceclasses.classname' => 'string',
'CmContentAddresses.uri' => 'string',
'CmContentAddresses.boxid' => 'string'
]
There is no technical need to follow the CamelCase conventions for the aliases, but for sure it doesn't hurt to generally stick to the conventions.
ps, if you setup the associations properly, then there should be no need to use manual joins, you could just use Query::contain() and Query::innerJoinWith() or Query::matching().
See
Cookbook > Database Access & ORM > Associations - Linking Tables Together
Cookbook > Database Access & ORM > Retrieving Data & Results Sets > Retrieving Associated Data
Cookbook > Database Access & ORM > Retrieving Data & Results Sets > Filtering by Associated Data

EF6 include/select multiple entity levels throws NotSupportedException

This seems very much similar to: EF4.1 multiple nested entity Includes gets NotSupportedException?
But the exception message is different and we are using a newer libraries.
Trying to load an entity graph with 3 levels made of: Accounting Record which contains multiple AccountingOperation(s) which in turn each of them contain multiple AccountingOperationLine(s). The exception below occurs if I want to load the 3 nevigation properties on the 3rd level (1 synthetical and 2 analytical accounts) as shown below.
Code:
var v = dbEntities.Set<AccountingRecord>()
.Include(ar => ar.AccountingRecordOperations.Select(
aro => aro.AccountingRecordOperationLines.Select(arol => arol.AccountingSynthetic)))
.Include(ar => ar.AccountingRecordOperations.Select(
aro => aro.AccountingRecordOperationLines.Select(arol => arol.AccountingAnalytical1)))
.Include(ar => ar.AccountingRecordOperations.Select(
aro => aro.AccountingRecordOperationLines.Select(arol => arol.AccountingAnalytical2)))
.ToList();
Exception
NotSupportedException: All objects in the EntitySet 'DbEntities.Entities' must have unique primary keys.
However, an instance of type '...AccountingSynthetic' and an instance of type '...AccountingRecordOperation' both have the same primary key value, 'EntitySet=Entities;ID=1104'
Something clearly confuses EF since AccountingSynthetic and AccountingRecordOperation don't share the id.
Configuration:
Model first
TPT
MySQL 5.6
MySQl Connector 6.8.3
EF 6.0
Notes:
All entities inherit of Entity.
The synthetic and analytical accounts all of them have a one to many relation to AccountingOperationLines (could this confuse EF?)
The error persist even with this simpler query like:
var v = dbEntities.Set<AccountingRecord>()
.Include(ar => ar.AccountingRecordOperations.Select(aro => aro.AccountingRecordOperationLines.Select(arol => arol.AccountingSynthetic)));

MAGENTO: cannot find catalog_product table. How does $installer->getTable('catalog/product') work then?

I looked through the file Mage/Catalog/sql/catalog_setup/install-1.6.0.0.php.
The part of code:
$installer = $this;
/* #var $installer Mage_Catalog_Model_Resource_Setup */
$installer->startSetup();
/**
* Create table 'catalog/product'
*/
$table = $installer->getConnection()
->newTable($installer->getTable('catalog/product'))
->addColumn('entity_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
'identity' => true,
'unsigned' => true,
'nullable' => false,
'primary' => true,
), 'Entity ID')
You can see here catalog_product implementation: $installer->getTable('catalog/product').
But I couldn't find this table in DB.
How does it work then? I always thought that catalog/product = catalog_product.
The following function
getTable('catalog/product')
can be traced back to
app/code/core/Mage/Core/Model/Resource.php
checking the public function getTableName($modelEntity) you will see that the logic treats also resource table names:
<catalog_resource>
<class>Mage_Catalog_Model_Resource</class>
<deprecatedNode>catalog_resource_eav_mysql4</deprecatedNode>
<entities>
<product>
<table>catalog_product_entity</table>
</product>
more resources about this:
Magento ORM: Entity Attribute Value; Part 1 and
Magento Setup Resources from Alan Storm
As is often the case in Magento, configuration is being used. Here's the call stack:
Mage_Core_Model_Resource_Setup::getTable('catalog/product')
Mage_Core_Model_Resource::getTableName('catalog/product');
When a '/' is present in the argument passed to the core/resource class's getTableName method, the configuration DOM is inspected. First the method will resolve the resourceModel node with the following line:
$resourceModel = (string) Mage::getConfig()->getNode()->global->models->{$model}->resourceModel;
Then, the core/resource class calls its getEntity() method, with the resourceModel node passed as the argument. This method simply looks under the resolved (resource) model node for the entity declaration (i.e. tablename):
Mage::getConfig()->getNode()->global->models->{$model}->entities->{$entity};
In the case of catalog/product, the above maps to:
Mage::getConfig()->getNode()->global->models->catalog_resource->entities->product;
If you look in Mage_Catalog's configuration xml, you'll see this borne out. The reason why it is best to access the tablename via configuration is that it is possible to specify table prefix, and using this method will return the correct name.