[Silverstripe 2.4]:如何获取包含一对多关系中的列的记录?

[Silverstripe 2.4]:如何获取包含一对多关系中的列的记录?,silverstripe,data-objects,Silverstripe,Data Objects,有两个数据对象类“A”和“B”具有一对多关系。我想从父数据对象和子数据对象中获取包含列的数据。如何在Silverstripe的ORM或SQL查询中实现这一点 示例:Dataobject“A”有两个事件,第一个事件包含一个日期信息(开始日期和结束日期)。第二个事件包含两个日期信息(开始日期和结束日期) 我想查询数据库以获取包含“A”和“B”列的信息,结果应该显示3行。一个来自“A”,两个来自“B” 我正在使用Silverstripe 2.4。一部电影可以有多个播放日期。Movie数据对象与Movi

有两个数据对象类“A”和“B”具有一对多关系。我想从父数据对象和子数据对象中获取包含列的数据。如何在Silverstripe的ORM或SQL查询中实现这一点

示例:Dataobject“A”有两个事件,第一个事件包含一个日期信息(开始日期和结束日期)。第二个事件包含两个日期信息(开始日期和结束日期)

我想查询数据库以获取包含“A”和“B”列的信息,结果应该显示3行。一个来自“A”,两个来自“B”

我正在使用Silverstripe 2.4。一部电影可以有多个播放日期。Movie数据对象与MovieDate数据对象具有一对多关系。我想从Movie中获取所有列,并重复与之关联的MovieDate的每个记录。这意味着若电影有两个日期,那个么我想要两张唱片

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;
}

}

您可以创建
DataObjectSet
,其中包含单独的
DataObject::get()调用的结果

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

$all = new DataObjectSet();

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

$all->sort('date','desc');
代码未经测试,但希望您能理解


编辑:这假设您使用的是SilverStripe 2.x-有关SS3.0的用法,请参阅,最明显的是
DataObject::get()
调用。

我认为您所追求的是“左连接”。
$a = DataObject::get(...);
$b = DataObject::get(...);

$all = new DataObjectSet();

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

$all->sort('date','desc');
不幸的是,silverstripe无法使用内置的ORM查询检索联接表上的数据(请参阅)

因此,您需要在此处使用普通sql查询:

    $query = "
        SELECT `Movie`.*, `MovieDate`.*
        FROM `Movie`
        LEFT JOIN `MovieDate` ON `Movie`.`ID` = `MovieDate`.`MovieID`
        ORDER BY `Movie`.`Title`
    ";
    $records = DB::query($query);
您现在可以使用
foreach
循环查看
$records

    foreach($records as $record) {
        print_r($record);
    }
有关更多信息,请参阅此论坛帖子:

请添加一些信息:您使用的是哪个silverstripe版本?你能发布dataobjects“A”和“B”的源代码吗?这是出于你的考虑而添加的。谢谢你的回复。现在,我正在获取子数据(MovieDate),以便在获取moviedataobject之后通过循环。现在,如何将电影中的字段组合到电影日期的每个记录/发生$members=Movie::get('Movie')$结果=新的DataObjectSet();foreach($members as$member){$result->merge($member->get('MovieDate');}echo“”;打印(结果);回声“;出口