0

1 対多の関係を持つ 2 つのデータオブジェクト クラス "A" と "B" があります。親と子の両方のデータオブジェクトから列を含むデータを取得したい。Silverstripe の ORM または SQL クエリでこれを実現する方法。

例: データオブジェクト "A" には 2 つのイベントがあり、最初のイベントには 1 つの日付情報 (開始日と終了日) が含まれています。2 番目のイベントには、2 つの日付情報 (開始日と終了日) が含まれています。

データベースにクエリを実行して、「A」と「B」の両方の列を含む情報を取得したいのですが、結果として3行が表示されるはずです。「A」から1つ、「B」から2つ。

Silverstripe 2.4 を使用しています。映画には複数の日付を表示できます。Movie データ オブジェクトは、MovieDate データ オブジェクトと 1 対多の関係にあります。関連する MovieDate の各レコードを繰り返す Movie からすべての列を取得したいと考えています。つまり、映画に 2 つの日付がある場合、2 つのレコードを取得したいということです

Title   Desc   StartDate   EndDate
-----   ----   ---------   -------
Matrix  AAA    2012-09-20  2012-09-20
Matrix  AAA    2012-09-29  2012-09-29

ここにあなたの親切な考慮のためのコードがあります

<?php
class Movie extends DataObject
{
 public static $db = array(
    'Title'    => 'Varchar',
    'Desc'     => 'Text',
 );

 public static $defaults = array(
      'RedirectionType' => 'Internal',
 );

 public static $has_one = array(
      'Image'         => 'Image',
      'Parent'        => 'Page',
      "LinkTo"        => "SiteTree"
 );

public static $has_many = array(
      'MovieDates'     => 'MovieDate'
 );

 static $summary_fields = array(
    'Title'      => 'Movie Title',
    'Desc'       => 'Movie Description'
 );

 function getRequirementsForPopup() {

      Requirements::customCSS("
        .iframe_wrap {
                top: 35%;
            }
      ");

 }

 public function getCMSFields()
 {
    $fields = new FieldSet(new TabSet('Root', $tab1 =  new Tab('Main')));

    $fields->addFieldsToTab('Root.Main', new TextField('Title', 'Movie Title'));
    $fields->addFieldsToTab('Root.Main', new TextareaField('Desc', 'Movie Description'));

    $tablefield = new DataObjectManager(
        $this,
        'MovieDates',
        'MovieDate',
        array('MovieStartDate' => 'Movie Start', 'MovieEndDate' => 'Movie End')
     );


    $tablefield->setPopupWidth(900);
    $tablefield->setAddTitle("Movie Date/Time");
    $fields->addFieldsToTab('Root.Main', $tablefield);
    $fields->addFieldsToTab('Root.Main', new LiteralField("Space", "</br></br></br></br></br>") );
    return $fields;
 }

}

    <?php
class MovieDate extends DataObject{
static $db = array(
    'MovieStartDate'             => 'Datetime',
    'MovieEndDate'               => 'Datetime',
);

static $has_one = array(
    'Movie' => 'Movie'
);

function getCMSFields(){

        $fields = new FieldSet();

        $movieStartDate = new DateField('MovieStartDate', 'Movie Start');
        $movieStartDate->setConfig('showcalendar', true);
        $fields->push($movieStartDate);

        $movieEndDate = new DateField('MovieEndDate', 'Movie End');
        $movieEndDate->setConfig('showcalendar', true);
        $fields->push($movieEndDate);

        $space = new LiteralField("Space", "</br></br></br></br></br>");
        $fields->push($space);

    return $fields;
}

}
4

2 に答える 2

0

あなたが求めているのは「左結合」だと思います。残念ながら、silverstripeには、組み込みのORMクエリを使用して結合されたテーブルのデータを取得する手段がありません(http://doc.silverstripe.org/framework/en/2.4/topics/datamodel#joiningを参照) 。

したがって、ここで単純なSQLクエリを使用する必要があります。

    $query = "
        SELECT `Movie`.*, `MovieDate`.*
        FROM `Movie`
        LEFT JOIN `MovieDate` ON `Movie`.`ID` = `MovieDate`.`MovieID`
        ORDER BY `Movie`.`Title`
    ";
    $records = DB::query($query);

$records次を使用してループすることができますforeach

    foreach($records as $record) {
        print_r($record);
    }

追加情報については、このフォーラムスレッドも参照してください: http ://www.silverstripe.org/general-questions/show/12745

于 2012-09-17T07:32:43.727 に答える
0

DataObjectSet個別のDataObject::get()呼び出しの結果を含むを作成できます。

$a = DataObject::get(...);
$b = DataObject::get(...);

$all = new DataObjectSet();

$all->merge($a);
$all->merge($b);

$all->sort('date','desc');

コードはテストされていませんが、うまくいけば、あなたはアイデアを得ることができます。完全なAPIを確認するには、DataObjectSetドキュメントを参照してください

編集:これは、SilverStripe2.xを使用していることを前提としています。SS3.0での使用、特にDataObject::get()呼び出しについては、更新された3.0データモデルのドキュメントを参照してください。

于 2012-09-14T21:13:47.137 に答える