D
D
Dmitry Igoshev2021-01-19 20:27:05
1C-Bitrix
Dmitry Igoshev, 2021-01-19 20:27:05

Bitrix ORM "correct" getList with OneToMany?

I'm trying to build the "correct" getList.
There are 2 entities connected through OneToMany and Reference on the other hand (multiple connection).
I make fetches getList()->fetch()/->fetchAll()/->fetchCollection();
Everything is fine until limit is added to the request.
If an entity has 2 related elements, then 2 "limits" will be "spent" on it. It doesn't matter how the result is processed.
Roughly speaking, if the first element has 2 children, then 4 rows instead of 5 will get into the selection (2 rows went to the first element).

I was able to build the query using ExpressionField and fetch_data_modification. The bottom line here is that I dynamically collect the id of the child elements into a string, and then in fetch_data_modification I get these objects with an additional request.
With such a crutch, limit works correctly, but: 1) it smells bad, 2) the modification function will have to be written to all related entities.

How to do it right? Does it even know how to work correctly with limit and OneToMany at the same time?

getList example

$arSelect   =   [
  '*',
    'SPECIALIZATION'
];
$arOrder    =   ['ID'=>'ASC'];
$limit      =   2;

$obResult   =   \K\Core\User\VerificationTable::getList([
    'select'=>  $arSelect,
    'order' =>  $arOrder,
    'limit' =>  $limit
])->fetchCollection();

echo count($obResult);

The result will be 1, not 2.

Mapping the underlying VerificationTable entity
public static function getMap():array{
    return  [
      (new Entity\IntegerField('ID'))
        ->configurePrimary()
        ->configureAutocomplete(),
      (new OneToMany(
        'SPECIALIZATION',
        '\K\Core\User\Verification\SpecializationTable',
        'VERIFICATION'
      )),
    ];
  }


Mapping a SpecializationTable subentity
public static function getMap():array{
    return  [
      (new Entity\IntegerField('ID'))
        ->configurePrimary()
        ->configureAutocomplete(),
      (new Entity\IntegerField('VERIFICATION_ID'))
        ->configureRequired(),
      (new Entity\ReferenceField('VERIFICATION',
        '\K\Core\User\VerificationTable',
        ['=this.VERIFICATION_ID'=>'ref.ID']
      ))->configureTitle(self::getMessage('K_CORE_FIELD_VERIFICATION_TITLE')),
    ];
  }

Answer the question

In order to leave comments, you need to log in

1 answer(s)
B
BookaZoid, 2021-12-16
@BookaZoid

I was helped by excluding the connection field from getList and then filling it with $collection->fill(['FIELDNAME']);

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question